Compare commits

...
10 Commits
Author SHA1 Message Date
Paul 8cbf30aa0d Fix GPG 2018-10-01 23:45:46 +02:00
Paul fc244f4009 Update oAuth tokens to be up-to-date 2018-10-01 22:12:35 +02:00
Paul 0f8ac914f8 Use Postgres 2018-10-01 21:17:02 +02:00
Paul 5c8f930bbd Add encryptie 2018-02-07 14:40:46 +01:00
Paul 5b31b09881 oauth 2018-02-07 09:54:48 +01:00
Paul d6bb65aa7f Add oauth 2018-02-07 09:51:49 +01:00
Paul e1e357e3ef Oauth worknig 2018-02-07 09:40:55 +01:00
Paul 80dd9e0d07 Django fixes 2018-02-05 17:14:03 +01:00
Paul 30b8c224c1 Introduce django project 2018-02-05 16:03:14 +01:00
Paul 29eeac4e78 Print 2018-02-05 08:52:53 +01:00
32 changed files with 867 additions and 100 deletions

No files matched your search

+4
View File
@@ -1 +1,5 @@
.DS_Store .DS_Store
__pycache__
/venv
db.sqlite3
/securityquiz/secrets.py
Executable
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "securityquiz.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
View File
Whitespace-only changes.
Executable
View File
Whitespace-only changes.
+23
View File
@@ -0,0 +1,23 @@
# Generated by Django 2.0.2 on 2018-02-05 13:50
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='LetsEncryptChallenge',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('challenge', models.CharField(max_length=128)),
('response', models.CharField(max_length=128)),
('expiry_date', models.DateTimeField()),
],
),
]
View File
Whitespace-only changes.
Executable
+7
View File
@@ -0,0 +1,7 @@
from django.db import models
class LetsEncryptChallenge(models.Model):
challenge = models.CharField(max_length=128)
response = models.CharField(max_length=128)
expiry_date = models.DateTimeField()
+5
View File
@@ -0,0 +1,5 @@
django
django-oauth-toolkit
django-cors-headers
pyopenssl
psycopg2
View File
Whitespace-only changes.
+4
View File
@@ -0,0 +1,4 @@
DB_HOST = ''
DB_NAME = ''
DB_USER = ''
DB_PASSWORD = ''
+118
View File
@@ -0,0 +1,118 @@
"""
Django settings for securityquiz project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import sys
from . import secrets
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
CLOSED = False
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'jk3nd2kj3nd2i30do23dn9283nd'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
if 'runserver' in sys.argv:
DEBUG = True
ALLOWED_HOSTS = ['websec.paulwagener.nl', '127.0.0.1']
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'quiz',
'oauth2_provider',
'corsheaders',
)
MIDDLEWARE = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
)
CORS_ORIGIN_ALLOW_ALL = True
ROOT_URLCONF = 'securityquiz.urls'
WSGI_APPLICATION = 'securityquiz.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': secrets.DB_NAME,
'USER': secrets.DB_USER,
'PASSWORD': secrets.DB_PASSWORD,
'HOST': secrets.DB_HOST
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__)) + '/..'
MEDIA_ROOT = PROJECT_PATH + '/media/'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [PROJECT_PATH + '/templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
STATICFILES_DIRS = (
PROJECT_PATH + '/static',
)
+15
View File
@@ -0,0 +1,15 @@
from django.conf.urls import include, url
from django.contrib import admin
import views
admin.autodiscover()
urlpatterns = [
# Examples:
url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
url(r'^api/hello', views.SecurityApi.as_view()),
url(r'^sign$', views.sign),
url(r'^letsencrypt$', views.letsencrypt),
url(r'^\.well-known/acme-challenge/(.+)', views.letsencrypt_challenge),
url(r'^(.*)$', views.home, name='home'),
]
+20
View File
@@ -0,0 +1,20 @@
"""
WSGI config for securityquiz project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
"""
import os, sys
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "securityquiz.settings")
path = '/var/www/security.aardappelschilmesje.nl'
if path not in sys.path:
sys.path.append(path)
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
+11
View File
@@ -17,6 +17,17 @@ figure img {
} }
} }
@media print {
#menu {
display: none;
}
#quiz {
border: 0 !important;
width: 100%;
margin-left: 0;
}
}
#difficulty { #difficulty {
width: 150px; width: 150px;
} }
+4 -47
View File
@@ -1,17 +1,10 @@
$(function () { $(function () {
var changed = false;
// Hints // Hints
$('.hint').replaceWith(function () {
return '<div><a href="#" class="hintlink" onclick="$(this).next().slideToggle(); return false;">Bekijk hint</a>' + $(this).hide()[0].outerHTML + '</div>';
function processHints() { });
$('.hint').replaceWith(function () { $('#difficulty').trigger('change');
return '<div><a href="#" class="hintlink" onclick="$(this).next().slideToggle(); return false;">Bekijk hint</a>' + $(this).hide()[0].outerHTML + '</div>';
});
$('#difficulty').trigger('change');
}
$('#difficulty').change(function (e) { $('#difficulty').change(function (e) {
var option = $(this).find(':selected').val(); var option = $(this).find(':selected').val();
@@ -34,40 +27,4 @@ $(function () {
}).prop('selected', true); }).prop('selected', true);
$('#difficulty').trigger('change'); $('#difficulty').trigger('change');
function loadPage(page) {
$('#quiz').load('/' + page + '.html?cachebuster=' + Math.random(), processHints);
}
function getPage(link) {
if (link.lastIndexOf('?') === -1) {
return '';
}
return link.substring(link.lastIndexOf('?') + 1);
}
// Dynamically load pages
$('#menu a').click(function (e, element) {
var page = getPage(e.target.href);
window.history.pushState({ page: page }, 'Security', e.target.href);
loadPage(page);
e.preventDefault();
});
window.onpopstate = function (event) {
if (event.state) {
loadPage(event.state.page);
} else {
window.location.href = '/';
}
}
// Load page
var page = getPage(window.location.href);
if (page !== '') {
loadPage(page);
} else {
loadPage('sql');
}
}); });
+9 -14
View File
@@ -1,17 +1,12 @@
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
owEBXgKh/ZANAwACAdVV8vX6nhxaAawuYglwbGFpbi50eHRVdLQaVGhlIE5hcndo owEBdgGJ/pANAwAIAQXMoUhwzjSpAawvYgpzZWNyZXQudHh0W7KUz1RoZSBOYXJ3
YWwgQmFjb25zIGF0IE1pZG5pZ2h0CokCHAQAAQIABgUCVXS0GgAKCRDVVfL1+p4c aGFsIEJhY29ucyBhdCBNaWRuaWdodAqJATMEAAEIAB0WIQTUzObaA3ShseyNi1AF
Wl31EACZ0itLnfLQrkFYGEa8DxgG6O101oc350JekBI7mIm1x556M3dIkyDTSqPd zKFIcM40qQUCW7KUzwAKCRAFzKFIcM40qQd2B/sEA5s/TiXM7GFplw2ocxegoIJS
1gY+5wE3iklSnqPAfRSskclQ5SahK7mIjRw8NoCpWGRdFT/2u15lZofqGMV23T1R TfqeGJoYJt0r5W6j+p2TQ07nH0vadqBpqEIgK9f3VQvUL89Triq0PLp6AgNdB+GR
hEuxxNlZwcWEWDg2Ixx6OqE836Qm+ITaS12ok5qDZFxj4hd4C7uinAv5CWKIyvwl a2M29x8hCEAZQX+Aj74YKfnso0F0EqP3e+Oj5oDrixstnPoy/hXlVbtnR9zvIJXh
l5ZwwWB4p+NT6JxY6p5Pw0J5xPVCE+pAFesPUwAYydQ5CabgdfRyjc6iMQz+GRFD Eme/pxHkIHnc4a2JojEQQIxu7WvYoXKcrGYPyX0/pvyWGAHIKcPtFNcnO2oF3rp7
Qs7kWuZ2JKPWm+2h0UQa38Id66fd4l38x16+rerIEG8XTMlfiXgtCPT9Rkdxb8lD GRzhc3tydqkIwevosHOsf4T0UoDb/4PAUvkfgbnSdbvGhAdLQtAMWl860lQRQ/WG
bZQJefupCPP/EAQnZOPzHFbZ32PaOnp0DTLi641W24rb0hwD2LPHIRh+KPWfwaVl oJaWC0hUOxzbSoHZeBH8+J8871e+jwE+j+6vk9lVj6Bz4c6O3mUOhxL+dkTw
+1BSEGE3STDjN0CGaTE1KDM5p5TEhML4/LwRucdp+y8c3f1gyWNd8ChnA9aCFr5w =FLte
h4FIpE1gAd6XANkVGCIHlZ0Lzxu022zjNFPW2sQeFJy1ZEqBAAwaOlnceztTyx6c
J+TNey4lYy2F4hVn/QxYF5kMUIEw22y4tMmwX4tOVkgg5I0X+mf2Csosbfz7Xsn3
0i4utcTqwmVov3obPQj1QprBeSMXoYSJMyUCO7eIE9eqeGy0uMO6xkG3Z2QGsZNS
aAzu9msSLIc5cQWx9Pva9pafC/sFIyJWudBlf8UEkeIFSll9FQ==
=h6Mi
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
View File
File renamed without changes.
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<title>Web Application Security</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="/static/css/bootstrap-responsive.min.css" rel="stylesheet" type="text/css">
<link href="/static/css/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/js/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="/static/js/jquery.base64.min.js"></script>
<script type="text/javascript" src="/static/js/quiz.js"></script>
</head>
<body>
<div class="row-fluid">
<div class="well span3" id="menu">
<h5>Web Application Security</h5>
<ul>
<li>
<a href="/sql">SQL Injection</a>
</li>
<li>
<a href="/xss">Cross-site Scripting</a>
</li>
<li>
<a href="/path">Insecure Direct Object References</a>
</li>
<li>
<a href="/wachtwoorden">Wachtwoorden</a>
</li>
<li>
<a href="/oauth">OAuth</a>
</li>
<li>
<a href="/certificaten">Certificaten</a>
</li>
<li>
<a href="/encryptie">Encryptie</a>
</li>
</ul>
Moeilijkheidsgraad:
<select id="difficulty">
<option value="easy">Hints zichtbaar</option>
<option value="normal">Hints optioneel</option>
<option value="hard">Geen hints</option>
</select>
<p>
<a href="/vm">Download VM</a>
</p>
</div>
<div id="quiz" class="span8 offset3">
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
+307
View File
@@ -0,0 +1,307 @@
{% extends "base.html" %} {% block content %}
<h1>Certificaten</h1>
<p>Bij dit onderdeel gaan we aan de slag met certificaten. De tool die we daarvoor gaan gebruiken is OpenSSL. Dit is een veelgebruikt
programma waar je vele cryptografische dingen mee kunt doen.</p>
<p>Op Linux en Mac OS X is deze tool al geïnstalleerd, Windows gebruikers moeten deze nog installeren. Als je
<a href="http://google.nl/?q=openssl+windows+install" target="_blank">zoekt op het internet</a> vindt je verschillende mogelijkheden om dat te doen. Bijvoorbeeld de v.1.1.0f Light versie op
<a href="http://slproweb.com/products/Win32OpenSSL.html" target="_blank">deze website</a>. Let op dat je dan op de Windows command line het hele pad moet gebruiken in plaats van alleen 'openssl'.
Bijvoorbeeld:
<span class="argument">C:\OpenSSL-Win32\bin\openssl.exe</span>
</p>
<p>Als je bij het gebruik van OpenSSL errors krijgt, probeer dan eerst je command prompt als Administrator te openen. En als
dat ook niet werkt om het volgende commando uit te voeren:</p>
<code class="terminal">SET OPENSSL_CONF=[pad naar bestand]\openssl.cfg</code>
<hr>
<blockquote>Wie ben jij? En waarom zou ik jou vertrouwen dat je bent wie je zegt dat je bent?</blockquote>
<p>Dat zijn vragen die webbrowsers elke dag moeten beantwoorden. Een site kan wel vinden dat het www.rabobank.nl is, maar daarmee
weet een browser nog niet zeker dat het ook daadwerkelijk de webserver van de Rabobank is. Misschien zit je eigenlijk te
communiceren met een server ergens in Rusland van een persoon die maar al te graag je inlogcodes wil weten.</p>
<p>Om dit probleem op te lossen zijn er certificaten bedacht en vastgelegd in de
<a href="http://en.wikipedia.org/wiki/X.509">X.509</a> standaard. Certificaten zijn kleine bestandjes waarin een identiteit staat beschreven. Dit is bijvoorbeeld een
certificaat van Paul Wagener:</p>
<img src="/static/img/certificaat.png" class="center-block" style="border: 1px solid black">
<p>Nu wil jij natuurlijk meteen een eigen certificaat voor jezelf hebben, en dat kan! Met dit alles-in-1 commando maak je een
certificaat dat helemaal van jou is:</p>
<code class="terminal">openssl req -x509 -nodes -newkey rsa:2048 -keyout sleutel.key -out certificaat.crt</code>
<p>Dit commando doet een paar dingen tegelijk waar we later op terugkomen. Nadat je de gevraagde informatie hebt ingevuld staat
er in het bestand certificaat.crt jouw certificaat. Met dit commando kan je je nieuwe certificaat bewonderen:</p>
<code class="terminal">openssl x509 -text -in certificaat.crt</code>
<div class="question">
<span class="question-string">Maak een certificaat met je eigen gegevens</span>
</div>
<p>Een certificaat heeft ook altijd een
<em>verstrekker</em> (issuer). Dit is de persoon of bedrijf die het certificaat heeft gemaakt en daarmee garant staat dat de
identiteit die op het certificaat staat ook klopt. In jouw certificaat staat dat je over jezelf hebt gezegd dat je bent
wie je zegt dat je bent. Niet echt betrouwbare informatie dus... Iedereen zou precies datzelfde certificaat kunnen maken.</p>
<p>Het wordt pas interessant en betrouwbaar als andere partijen het certificaat verstrekken en zo kunnen zeggen dat ze de gegevens
van het certificaat gecontroleerd hebben. Als jij die verstrekker vertrouwt dat hij zijn werk goed doet met de correctheid
van certificaten controleren. Dan vertrouw je ook indirect de gegevens op het certificaat. Zo hoef je maar een handjevol
verstrekkers te vertrouwen om bijna alle websites op het internet te kunnen vertrouwen.</p>
<p>Elke besturingssysteem heeft een lijst van basis verstrekkers die ze impliciet vertrouwen, deze lijst kan je bekijken en
veranderen door in je geavanceerde browserinstellingen op zoek te gaan naar een knop 'Beheer certificaten' (te vinden in
het Advanced -> Certificates tabblad in Firefox).</p>
<p>
<div class="question">
<span class="question-string">Hoeveel basis verstrekkers vertrouwt jouw systeem?</span>
</div>
<div class="question">
<span class="question-string">Bekijk het certificaat van
<a href="https://facebook.com/" target="_blank">Facebook</a>, welk bedrijf heeft dit certificaat verstrekt?</span>
</div>
<p class="hint">Hint: Het certificaat kan je in de meeste browsers bekijken door op het slot-ikoontje te klikken. In Chrome moet je de
Developer Tools openen en kijken in het mapje 'Security'.</p>
<h2>Mag ik uw handtekening?</h2>
<p>Zo'n certificaat wat je aan jezelf hebt verstrekt vertrouwd natuurlijk niemand. We moeten eerst iemand vinden die jouw
certificaat wil ondertekenen.</p>
<p>Er is een speciaal bestandsformaat om aan een verstrekker te vragen of hij jouw certificaat wil ondertekenen:
<b>.csr</b>. Dat staat voor Certificate Signing Request. Een soort van bedelbrief die je rond kan sturen met je certificaat
waar nog een verstrekker bij moet.</p>
<p>Je kan onderstaand commando gebruiken om je eigen gemaakte certificaat als basis te gebruiken voor zo'n Certificate Signing
Request:
</p>
<code class="terminal">openssl x509 -x509toreq -in certificaat.crt -signkey sleutel.key -out certificaat_verzoek.csr</code>
<p>Zo'n verzoekje kan je vervolgens bij een certificaat autoriteit zoals Thawte of VeriSign inleveren. Voor een paar honderd
euro zijn ze dan bereid om hun handtekening eronder te zetten.</p>
<p>Om deze cursus relatief goedkoop te houden heeft deze site ook een certificaat autoriteit waar je certificaten kan laten
ondertekenen:
<a href="/sign" target="signen">Certificaat Autoriteit</a>. Gebruik deze site om jouw certificaat te laten ondertekenen</p>
<div class="question">
<span class="question-string">Bekijk het certificaat wat je hebt teruggekregen. Welke persoon heeft dit certificaat aan jou verstrekt?</span>
</div>
<h2>Zelf verstrekken</h2>
<blockquote>Sometimes, the only one you can trust is yourself.</blockquote>
<p>Om zelf verstrekker te spelen heb je helemaal geen speciale certificaten nodig. Je kan namelijk gewoon je eigen certificaat
en sleutel gebruiken die je aan het begin van de les hebt gemaakt.</p>
<div class="question">
<span class="question-string">Vraag een medecursist om een Certificate Signing Request van zijn certificaat te geven en onderteken dat met je eigen
certificaat. Zoek op internet het commando op waarmee je dat kan doen.</span>
</div>
<p>Tip: zorg ervoor dat jouw certificaat standaard wordt geinstalleerd op alle besturingsystemen. Dan kan je goud geld verdienen
met het ondertekenen van andere certificaten ;)</p>
<!--
<h2>Websites beveiligen</h2>
<p>Leuk die certificaten, maar laten we niet vergeten dat we er ook nog wat nuttigs mee kunnen doen. Namelijk onze internetverbindingen
beveiligen. Om hiermee te oefenen moet je
<a href="/static/vm.zip">deze virtual machine</a> downloaden. Het wachtwoord van deze VM is
<b>
<i>sec2</i>
</b>. We hebben een aantal dingen gewijzigd hierin:</p>
<ul>
<li>Er is een default Apache installatie aanwezig.</li>
<li>www.security2.nl en websec.paulwagener.nl wijzen naar de geïnstalleerde Apache op localhost.</li>
<li>We hebben
<a href="/sign" target="signen">deze verstrekker</a> en het Let's Encrypt test certificaat als vertrouwd toegevoegd aan het systeem (dit kan je terugvinden
als je in je browser gaat kijken naar alle certificaten die zijn geïnstalleerd)</li>
</ul>
<p>Controleer eerst of de site http://www.security2.nl in jouw VM te bereiken is, en via http
<b>s</b>://www.security2.nl/ nog niet te bereiken is. Je gaat de site in de volgende opgaven beveiligen met SSL, om dat
te doen moeten we eerst SSL aanzetten in Apache met de volgende commando's:</p>
<code class="terminal">sudo a2enmod ssl<br>
sudo a2ensite default-ssl<br>
sudo service apache2 reload</code>
<p class="hint">Hint: Commando's vul je in in het programma 'Terminal'</p>
<p>De site is nu ook via https:// bereikbaar, maar Apache heeft een ongeldig dummy certificaat gebruikt om de site te beveiligen.
Om het werkend te krijgen moeten we eerst de volgende stappen uitvoeren:</p>
<ol>
<li>Maak een geheel nieuwe certificaat/sleutel combo aan met het commando bovenaan de pagina. Je mag alles invullen zoals
je wil, behalve de Common Name / Server FQDN. Die moet
<code>www.security2.nl</code> zijn.</li>
<li>Laat het certificaat
<a href="/sign" target="signen">hier</a> weer ondertekenen</li>
<li>Kopieer het sleutel bestand en het ondertekende certificaat naar de VM</li>
<li>Voer het volgende commando uit:
<code class="terminal">sudo gedit /etc/apache2/sites-available/default-ssl.conf</code> om de standaard SSL configuratie aan te passen.</li>
<li>Verander in dit bestand de
<code>SSLCertificateFile</code> en
<code>SSLCertificateKeyFile</code> zodat ze naar jouw certificaat en sleutel bestand wijzen</li>
<li>Maak je wijzigingen actief door de configuratie opnieuw in te laden:
<code class="terminal">sudo service apache2 reload</code>
</li>
</ol>
<p>Als je alles goed hebt gedaan is de site nu met SSL beveiligd! Controleer of je de site in de VM nu kan bereiken via https://www.security2.nl/
(Alleen Chrome werkt, certificaat is niet aan Firefox toegevoegd). Als je een groen slotje krijgt mag je de volgende
vraag beantwoorden:</p>
<div class="question">
<span class="question-string">Plak de inhoud van het .crt bestand dat je hebt gebruikt om de website te beveiligen met een groen slotje. (inclusief
begin en einde
<code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_ssl_cert.points max="10" %}
<textarea class="question-input" name="answer_openssl_ssl_cert">{{ answers.answer_openssl_ssl_cert.string }}</textarea>
</div>
<div class="question">
<span class="question-string">Maak een screenshot van het groene slotje en de details van het certificaat en upload die naar
<a href="http://imgur.com" target="_blank">imgur</a>. Plak de URL naar die screenshot als antwoord.</span>
{% include "points.html" with points=answers.answer_openssl_screenshot.points max="10" %}
<input class="question-input" name="answer_openssl_screenshot" type="url" value="{{ answers.answer_openssl_screenshot.string }}">
</div>
<img src="/static/img/slotje_certificaat_vm.png" class="center-block screenshot" style="width: 60%">
<h2>Let's Encrypt</h2>
<img src="/static/img/letsencrypt_logo.png" class="center-block">
<p>
<b>
</b>
</p>
<p>Sinds 2015 is er
<a href="https://letsencrypt.org/">een nieuwe speler</a> op de markt die gratis certificaten verstrekt, mits je kan bewijzen dat jouw website van jouw is
natuurlijk. Dit gaat met behulp van de command-line
<code>letsencrypt</code> tool die automatisch certificaten maakt en ondertekend voor jouw website. Deze tool hebben we al voor je geinstalleerd
in de VM.</p>
<p>We gaan nu websec.paulwagener.nl beveiligen, niet deze website die je nu aan het bekijken bent, maar weer de localhost
die in de VM draait. Maar nu gaan we hem met behulp van Let's Encrypt beveiligen.</p>
<p>
<i>Tip:</i>Je mag voor deze opdracht ook een eigen domein dat je hebt beveiligen! Let even op dat de commando's dan niet
overal exact hetzelfde zijn. Zeker als je geen Apache gebruikt.</p>
<p>Controleer eerst dat
<b>https</b>://websec.paulwagener.nl// in de VM een fout geeft, dat komt omdat het certificaat van de vorige opdracht nog
steeds van www.security2.nl is (als je de vorige opdracht goed hebt gedaan, anders krijg je misschien een andere fout).
De browser ziet dat dat niet hetzelfde domein is en geeft terecht een error.</p>
<p>We gaan beginnen met het aanvragen van een certificaat. Dit doen we met het volgende commando:
<code class="terminal">sudo letsencrypt certonly --manual --staging</code>
<p>Even een korte uitleg van dit commando:</p>
<ul>
<li>
<b>sudo</b>: letsencrypt heeft root rechten nodig, we moeten letsencrypt dus altijd met root rechten uitvoeren</li>
<li>
<b>letsencrypt</b>: de naam van het scriptje zelf. Als je dit op je eigen server wil doen moet je deze eerst installeren
(instructies vind je op de
<a href="https://letsencrypt.org/getting-started/">Let's Encrypt website</a> zelf). Afhankelijk van hoe letsencrypt is geinstalleerd kan het commando ook
<code>letsencrypt-auto</code>,
<code>certbot</code> of
<code>certbot-auto</code> zijn.</li>
<li>
<b>certonly</b>: Standaard wil Let's Encrypt volledig automatisch Apache voor je herconfigureren, maar dat gaat bij
ons niet werken omdat de VM niet
<i>echt</i> websec.paulwagener.nl is. Met de certonly optie geven we aan dat we alleen geinteresseerd zijn in het maken
van nieuwe certificaten.</li>
<li>
<b>--manual</b>: De Let's Encrypt servers geven niet zomaar certificaten weg, ze willen altijd zeker weten dat het domein
waar je een certificaat van aanvraagt ook echt van jou is. Er zijn verschillende manieren om dat te doen, maar ze
komen er allemaal op neer dat je een specifiek bestandje moet hosten op je website. Met de manual optie moeten we
onze webserver zelf goed configureren dat het bestandje te bereiken is via het domein. De andere opties (
<code>--webroot</code>,
<code>--apache</code>) proberen het bestandje automatisch te plaatsen en de webserver te configureren. Dat gaat voor deze opdracht niet
werken omdat de echte websec.paulwagener.nl veilig ergens draait en van buiten niet te configureren is.</li>
<li>
<b>--staging</b>: Deze optie zorgt ervoor dat je een certificaat krijgt van de test server in plaats van de echte server.
Deze hebben we nodig omdat de echte server een limiet heeft van 5 certificaataanvragen per week per domein. En dat
is voor dit vak niet handig. Nadeel van de testserver is dat de certificaten een ongeldige fake verstrekker hebben
(in de VM hebben we die fake verstrekker toegevoegd als vertrouwd, zodat je alsnog een groen slotje krijgt.)</li>
</ul>
<p>Als je dit commando voor de eerste keer uitvoert wordt er gevraagd naar je e-mailadres, daar kan je invullen wat je wil.
Voor het domein gaan we websec.paulwagener.nl invullen. Als je je eigen domein wil beveiligen vul je hier uiteraard
je eigen domein in.</p>
<img src="/static/img/letsencrypt_domain.png" class="center-block screenshot" style="width: 80%">
<p>Let's Encrypt vraagt daarna om een bestandje op de server te zetten in een hele specifieke map (.well-known/acme-challenge)
op de echte websec.paulwagener.nl server. Normaliter zou dit een probleem zijn, want dat kan alleen als je toegang
hebt tot de server. Maar speciaal voor jullie is er
<a href="/letsencrypt">een pagina</a> waar je de code kan kopieren en er voor zorgen dat het bestandje 10 minuten lang op onze server wordt
gehost!
</p>
<img src="/static/img/letsencrypt_challenge.png" class="center-block screenshot" style="width: 80%">
<p>Nadat de challenge is geslaagd zal Let's Encrypt nog een melding geven over dat de self-verification failed (in de VM
wijst websec.paulwagener.nl immers naar de localhost, en niet naar het bestandje op de echte server). Maar dat kan
je negeren, als het goed is gegaan staan de certificaten nu in de map
<code>/etc/letsencrypt/live/websec.paulwagener.nl</code>!.
<img src="/static/img/letsencrypt_congrats.png" class="center-block screenshot" style="width: 80%">
<p>Met dit commando kan je je nieuwe certificaat bekijken:</p>
<code class="terminal">sudo gedit /etc/letsencrypt/live/websec.paulwagener.nl/fullchain.pem</code>
<div class="question">
<span class="question-string">Plak de inhoud van het
<code>fullchain.pem</code> certificaat voor websec.paulwagener.nl. (inclusief alle begin en einde
<code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_letsencrypt_fullchain.points max="0" %}
<textarea class="question-input" name="answer_openssl_letsencrypt_fullchain">{{ answers.answer_openssl_letsencrypt_fullchain.string }}</textarea>
</div>
<p>Stel het default-ssl.conf configuratie bestand van Apache nu zo in dat het de certificaten van Let's Encrypt gebruikt:</p>
<img src="/static/img/letsencrypt_conf.png" class="center-block screenshot">
<p>Sla het bestand op, reload Apache en als het goed is heb je nu een beveiligde https://websec.paulwagener.nl/, helemaal
gratis en voor niets!</p>
<img src="/static/img/letsencrypt_chrome.png" class="center-block screenshot" style="width: 90%">
<p>Het zal je misschien opvallen dat de verstrekker Fake is, dat komt omdat we de
<code>--staging</code> optie hebben gebruikt. In de VM is deze toegevoegd als iets dat we kunnen vertrouwen (en dus een groen slotje oplevert),
maar in de echte wereld is dat niet zo. Zorg er dus bij je eigen website zo dat je niet de --staging optie gebruikt
als je voor de echie certificaten aan het maken bent</p>
<div class="question">
<span class="question-string">Maak een screenshot van het groene slotje en de details van het certificaat (zoals hierboven, maar natuurlijk niet
letterlijk dat plaatje, dat hebben we door) en upload die naar
<a href="http://imgur.com" target="_blank">imgur</a>. Plak de URL naar die screenshot als antwoord.</span>
{% include "points.html" with points=answers.answer_openssl_letsencrypt_screenshot.points max="0" %}
<input class="question-input" name="answer_openssl_letsencrypt_screenshot" type="url" value="{{ answers.answer_openssl_letsencrypt_screenshot.string }}">
</div>
-->
{% endblock %}
+6 -4
View File
@@ -185,7 +185,7 @@
<p>Om het makkelijker te maken om publieke sleutels uit te wisselen kan GPG gebruik maken van een <p>Om het makkelijker te maken om publieke sleutels uit te wisselen kan GPG gebruik maken van een
<b>keyserver</b>. Dit is een speciale server die een lijst van publieke sleutels bijhoud. Voor onderstaande opdrachten hebben <b>keyserver</b>. Dit is een speciale server die een lijst van publieke sleutels bijhoud. Voor onderstaande opdrachten hebben
we onze eigen keyserver ingericht op websec.paulwagener.nl. we onze eigen keyserver ingericht op websec.paulwagener.nl.
<b>Deze werkt niet als je de opdrachten thuis maakt</b>. De Avans firewall blokkeert poort 11371 waarop deze server werkt.</p> <b>Deze werkt niet als je de opdrachten thuis maakt</b>. De firewall blokkeert poort 11371 waarop deze server werkt.</p>
<p>GPG kan je <p>GPG kan je
<a href="http://www.gpg4win.org/" target="_blank">hier</a> voor Windows downloaden, na het installeren kan je in je CMD alle commando's typen. Als je Linux of Mac OS X <a href="http://www.gpg4win.org/" target="_blank">hier</a> voor Windows downloaden, na het installeren kan je in je CMD alle commando's typen. Als je Linux of Mac OS X
@@ -224,7 +224,7 @@
<p> <p>
<p>Haal van de keyserver onze publieke sleutel op met sleutel-ID <p>Haal van de keyserver onze publieke sleutel op met sleutel-ID
<b>B69F77232CE5546445137725D555F2F5FA9E1C5A</b> (GPG noemt dit ook wel de user-ID). We hebben met onze private sleutel <b>D4CCE6DA0374A1B1EC8D8B5005CCA14870CE34A9</b> (GPG noemt dit ook wel de user-ID). We hebben met onze private sleutel
een tekst versleuteld in een tekst versleuteld in
<a href="static/secret.txt.asc" target="_blank">dit bestand</a>. Gebruik de publieke sleutel om dit bestand te ontsleutelen.</p> <a href="static/secret.txt.asc" target="_blank">dit bestand</a>. Gebruik de publieke sleutel om dit bestand te ontsleutelen.</p>
@@ -282,7 +282,7 @@
<p>Op die manier ontstaat er een web van vertrouwensrelaties. En als jij Tony vertrouwd, en Tony vertrouwd Steve. Dan <p>Op die manier ontstaat er een web van vertrouwensrelaties. En als jij Tony vertrouwd, en Tony vertrouwd Steve. Dan
kan je indirect ervan uitgaan dat de naam van de sleutel van Steve klopt. Op die manier kan je indirect een hele kan je indirect ervan uitgaan dat de naam van de sleutel van Steve klopt. Op die manier kan je indirect een hele
hoop sleutels vertrouwen. Op onze keyserver zie je bijvoorbeeld hoop sleutels vertrouwen. Op onze keyserver zie je bijvoorbeeld
<a href="http://websec.paulwagener.nl:11371/pks/lookup?op=vindex&search=0XB69F77232CE5546445137725D555F2F5FA9E1C5A" target="_blank">wie er allemaal direct onze sleutel vertrouwd.</a> <a href="http://websec.paulwagener.nl:11371/pks/lookup?op=vindex&search=0XD4CCE6DA0374A1B1EC8D8B5005CCA14870CE34A9" target="_blank">wie er allemaal direct onze sleutel vertrouwd.</a>
</p> </p>
<img src="static/img/web_of_trust.gif"> <img src="static/img/web_of_trust.gif">
@@ -292,7 +292,7 @@
sleutel weer opnieuw te versturen naar de keyserver.</p> sleutel weer opnieuw te versturen naar de keyserver.</p>
<div class="question"> <div class="question">
<span class="question-string">Gebruik je eigen sleutel om onze sleutel (sleutel-ID: B69F77232CE5546445137725D555F2F5FA9E1C5A) en de sleutel van <span class="question-string">Gebruik je eigen sleutel om onze sleutel (sleutel-ID: D4CCE6DA0374A1B1EC8D8B5005CCA14870CE34A9) en de sleutel van
drie medestudenten te ondertekenen. Upload je ondertekening terug naar de keyserver. Plak je eigen sleutel-ID als drie medestudenten te ondertekenen. Upload je ondertekening terug naar de keyserver. Plak je eigen sleutel-ID als
antwoord hier.</span> antwoord hier.</span>
{% include "points.html" with points=answers.answer_encryption_sign_keys.points max="5" %} {% include "points.html" with points=answers.answer_encryption_sign_keys.points max="5" %}
@@ -310,3 +310,5 @@
<a href="http://xkcd.com/364/" target="_blank"> <a href="http://xkcd.com/364/" target="_blank">
<img src="http://imgs.xkcd.com/comics/responsible_behavior.png"> <img src="http://imgs.xkcd.com/comics/responsible_behavior.png">
</a> </a>
{% endblock %}
+4 -2
View File
@@ -29,11 +29,13 @@
<li> <li>
<a href="/?wachtwoorden">Wachtwoorden</a> <a href="/?wachtwoorden">Wachtwoorden</a>
</li> </li>
<li>
<!-- <a href="/?certificaten">Certificaten</a>
</li>
<li> <li>
<a href="/?oauth">OAuth</a> <a href="/?oauth">OAuth</a>
</li> </li>
<!--
<li> <li>
<a href="/?certificaten">Certificaten</a> <a href="/?certificaten">Certificaten</a>
</li> </li>
File renamed without changes.
+9 -31
View File
@@ -111,12 +111,6 @@
<img src="static/img/oauth_register.png" style="width: 50%"> <img src="static/img/oauth_register.png" style="width: 50%">
</figure> </figure>
<div class="question">
<span class="question-string">Wat is de client_id die je hebt geregistreerd?</span>
{% include "points.html" with points=answers.answer_oauth_client_id.points max="5" %}
<input class="question-input" name="answer_oauth_client_id" value="{{ answers.answer_oauth_client_id.string }}"></input>
</div>
<p>Elke OAuth server heeft twee endpoints (lees: URL's): de authorisatie endpoint en de token endpoint. Hieronder zie je de <p>Elke OAuth server heeft twee endpoints (lees: URL's): de authorisatie endpoint en de token endpoint. Hieronder zie je de
endpoints van een aantal bekende servers:</p> endpoints van een aantal bekende servers:</p>
@@ -128,8 +122,8 @@
</tr> </tr>
<tr> <tr>
<td>Deze cursus</td> <td>Deze cursus</td>
<td>http://websec.paulwagener.nl/o/authorize/</td> <td>https://websec.paulwagener.nl/o/authorize/</td>
<td>http://websec.paulwagener.nl/o/token/</td> <td>https://websec.paulwagener.nl/o/token/</td>
</tr> </tr>
<tr> <tr>
<td>GitHub</td> <td>GitHub</td>
@@ -179,13 +173,11 @@
<p>Voor deze site is de authorisatie URL: <p>Voor deze site is de authorisatie URL:
<br> <br>
<span class="url">http://websec.paulwagener.nl/o/authorize/?client_id=(CLIENT_ID)&amp;response_type=token</span> <span class="url">https://websec.paulwagener.nl/o/authorize/?client_id=(CLIENT_ID)&amp;response_type=token</span>
</p> </p>
<div class="question"> <div class="question">
<span class="question-string">Authoriseer met je eigen client id. Welke access token heb je gekregen?</span> <span class="question-string">Authoriseer met je eigen client id. Welke access token heb je gekregen?</span>
{% include "points.html" with points=answers.answer_oauth_implicit_access_token.points max="5" %}
<input class="question-input" name="answer_oauth_implicit_access_token" value="{{ answers.answer_oauth_implicit_access_token.string }}"></input>
</div> </div>
<p class="hint"> <p class="hint">
@@ -194,8 +186,6 @@
<div class="question"> <div class="question">
<span class="question-string">Hoeveel seconden is deze token code geldig?</span> <span class="question-string">Hoeveel seconden is deze token code geldig?</span>
{% include "points.html" with points=answers.answer_oauth_implicit_access_token_expires.points max="5" %}
<input class="question-input" name="answer_oauth_implicit_access_token_expires" value="{{ answers.answer_oauth_implicit_access_token_expires.string }}"></input>
</div> </div>
<p>De access token kan je nu gebruiken om een request te doen naar <p>De access token kan je nu gebruiken om een request te doen naar
@@ -211,8 +201,6 @@
<div class="question"> <div class="question">
<span class="question-string">Wat is de geheime code die gestuurd wordt als je de API aanroept?</span> <span class="question-string">Wat is de geheime code die gestuurd wordt als je de API aanroept?</span>
{% include "points.html" with points=answers.answer_oauth_api_hello.points max="10" %}
<input class="question-input" name="answer_oauth_api_hello" value="{{ answers.answer_oauth_api_hello.string }}"></input>
</div> </div>
<p class="hint"> <p class="hint">
@@ -246,8 +234,6 @@
<div class="question"> <div class="question">
<span class="question-string">Welke authorisatie code heb je gekregen?</span> <span class="question-string">Welke authorisatie code heb je gekregen?</span>
{% include "points.html" with points=answers.answer_oauth_authorization_code.points max="5" %}
<input class="question-input" name="answer_oauth_authorization_code" value="{{ answers.answer_oauth_authorization_code.string }}"></input>
</div> </div>
<img src="static/img/oauth_authorization_code.png" style="width: 25%; float: right"> <img src="static/img/oauth_authorization_code.png" style="width: 25%; float: right">
@@ -283,8 +269,6 @@
<div class="question"> <div class="question">
<span class="question-string">Copy paste de response die je hebt gekregen waar de refresh token in staat</span> <span class="question-string">Copy paste de response die je hebt gekregen waar de refresh token in staat</span>
{% include "points.html" with points=answers.answer_oauth_refresh_token.points max="5" %}
<textarea class="question-input" name="answer_oauth_refresh_token">{{ answers.answer_oauth_refresh_token.string }}</textarea>
</div> </div>
<img src="static/img/oauth_refresh_token.png" style="float: right; width: 25%"> <img src="static/img/oauth_refresh_token.png" style="float: right; width: 25%">
@@ -300,9 +284,9 @@
<p>Bij Google hebben we een OAuth client geregistreerd en de volgende gegevens gekregen:</p> <p>Bij Google hebben we een OAuth client geregistreerd en de volgende gegevens gekregen:</p>
<code style="display: block;"> <code style="display: block;">
Client id: 799427728270-ahr6bg713mtkh2htskbmqko8hpheq1md.apps.googleusercontent.com<br> Client id: 507532281075-92u6kon3r2kpesqbadmt29cnlvtpjbkh.apps.googleusercontent.com<br>
Client secret: 3W9FcQefBmhX7CT1FgzqiCdR<br> Client secret: yTmMOl9GfCFl-F4QoESfi7HT<br>
Refresh token: 1/WfdEEjWgj5Lm8p6wZzoTCeirQz7e4hMDIxvOkdvSjsU<br></code> Refresh token: 1/EpIRGrHcCV8wi54zGwJoKUklSTkndrJvj1mixqNrgkY"<br></code>
<p>Met deze gegevens kunnen we weer een POST doen naar de token endpoint (voor Google: https://accounts.google.com/o/oauth2/token) <p>Met deze gegevens kunnen we weer een POST doen naar de token endpoint (voor Google: https://accounts.google.com/o/oauth2/token)
om een access token te genereren. Dit keer hoeven we geen redirect_uri mee te sturen en moeten we de grant_type parameter om een access token te genereren. Dit keer hoeven we geen redirect_uri mee te sturen en moeten we de grant_type parameter
@@ -314,16 +298,14 @@
<img src="static/img/oauth_google_refresh.png" class="screenshot" style="width: 70%; margin: 20px; display: block"> <img src="static/img/oauth_google_refresh.png" class="screenshot" style="width: 70%; margin: 20px; display: block">
<p>Gebruik de access token die je krijgt om een API call te doen naar <p>Gebruik de access token die je krijgt om een API call te doen naar
<span class="url">https://www.googleapis.com/calendar/v3/calendars/websecpaulwagener@gmail.com/events</span>. Vergeet niet weer de juiste <span class="url">https://www.googleapis.com/calendar/v3/calendars/websec.paulwagener@gmail.com/events</span>. Vergeet niet weer de juiste Authorization
Authorization header te gebruiken om je access token in te zetten! Als je het goed doet krijg je alle events uit onze Google header te gebruiken om je access token in te zetten! Als je het goed doet krijg je alle events uit onze Google Calender
Calender te zien in JSON formaat.</p> te zien in JSON formaat.</p>
<img src="static/img/oauth_google_call_api.png" class="screenshot" style="width: 70%; margin: 20px; display: block"> <img src="static/img/oauth_google_call_api.png" class="screenshot" style="width: 70%; margin: 20px; display: block">
<div class="question"> <div class="question">
<span class="question-string">Wat is de code die in de Geheime afspraak staat? </span> <span class="question-string">Wat is de code die in de Geheime afspraak staat? </span>
{% include "points.html" with points=answers.answer_oauth_calendar_secret_code.points max="10" %}
<input class="question-input" name="answer_oauth_calendar_secret_code" value="{{ answers.answer_oauth_calendar_secret_code.string }}"></input>
</div> </div>
<p>Genoeg tutorial, tijd voor het echte werk! We gaan handmatig het hele OAuth proces doorlopen voor een Google API. Dat mag <p>Genoeg tutorial, tijd voor het echte werk! We gaan handmatig het hele OAuth proces doorlopen voor een Google API. Dat mag
@@ -350,8 +332,6 @@
<div class="question"> <div class="question">
<span class="question-string">Beschrijf de HTTP requests die je hebt gemaakt om de token te krijgen EN de API te gebruiken (en ook de uitkomst van die <span class="question-string">Beschrijf de HTTP requests die je hebt gemaakt om de token te krijgen EN de API te gebruiken (en ook de uitkomst van die
requests). Gevoelige data mag je met ***** censureren.</span> requests). Gevoelige data mag je met ***** censureren.</span>
{% include "points.html" with points=answers.answer_oauth_google_requests.points max="15" %}
<textarea class="question-input" name="answer_oauth_google_requests" style="height: 200px">{{ answers.answer_oauth_google_requests.string }}</textarea>
</div> </div>
<h3>Mini webapp</h3> <h3>Mini webapp</h3>
@@ -364,8 +344,6 @@
<div class="question"> <div class="question">
<span class="question-string">Plak de broncode van je webapplicatie in het tekstvak</span> <span class="question-string">Plak de broncode van je webapplicatie in het tekstvak</span>
{% include "points.html" with points=answers.answer_oauth_web_app.points max="20" %}
<textarea class="question-input" name="answer_oauth_web_app" style="height: 200px">{{ answers.answer_oauth_web_app.string }}</textarea>
</div> </div>
{% endblock %} {% endblock %}
+4
View File
@@ -1,3 +1,5 @@
{% extends 'base.html' %} {% block content %}
<h1>Insecure Direct Object References</h1> <h1>Insecure Direct Object References</h1>
<img src="/static/img/imgr.png"> <img src="/static/img/imgr.png">
@@ -76,3 +78,5 @@
<div class="question"> <div class="question">
<span class="question-string">Beschrijf hoe je met deze site de inhoud van /etc/geheim.txt kan achterhalen</span> <span class="question-string">Beschrijf hoe je met deze site de inhoud van /etc/geheim.txt kan achterhalen</span>
</div> </div>
{% endblock %}
File renamed without changes.
View File
File renamed without changes.
+2
View File
@@ -1,3 +1,4 @@
{% extends 'base.html' %} {% block content %}
<style> <style>
code i { code i {
color: blue; color: blue;
@@ -220,3 +221,4 @@
een diep donker geheim die het niet toont aan de wereld, er is een geheime pagina met id 0.</p> een diep donker geheim die het niet toont aan de wereld, er is een geheime pagina met id 0.</p>
<p>Geen hints en geen broncode deze keer. Aan jullie de taak om de site te hacken (meerdere manieren mogelijk).</p> <p>Geen hints en geen broncode deze keer. Aan jullie de taak om de site te hacken (meerdere manieren mogelijk).</p>
{% endblock %}
+4
View File
@@ -1,3 +1,5 @@
{% extends 'base.html' %}{% block content %}
<h1>Virtuele machine</h1> <h1>Virtuele machine</h1>
<p>Tijdens deze cursus gaan we hacken leren door het te doen. Helaas voor ons zijn de meeste bedrijfsnetwerken zeer pinnig op <p>Tijdens deze cursus gaan we hacken leren door het te doen. Helaas voor ons zijn de meeste bedrijfsnetwerken zeer pinnig op
@@ -26,3 +28,5 @@
<li>Maak een <li>Maak een
<a href="https://www.ubuntu.com/download/desktop" target="_blank">Ubuntu</a> VM en ga in deze VM met Firefox naar het IP adres</li> <a href="https://www.ubuntu.com/download/desktop" target="_blank">Ubuntu</a> VM en ga in deze VM met Firefox naar het IP adres</li>
</ul> </ul>
{% endblock %}
@@ -1,3 +1,5 @@
{% extends 'base.html' %} {% block content %}
<h1>Wachtwoorden</h1> <h1>Wachtwoorden</h1>
<img src="/static/img/password.png" class="center-block"> <img src="/static/img/password.png" class="center-block">
@@ -35,7 +37,8 @@
</i>. Aanvallers hebben de hashes van alle veel gebruikte wachtwoorden, korte lettercombinaties en woordenboekwoorden al berekend </i>. Aanvallers hebben de hashes van alle veel gebruikte wachtwoorden, korte lettercombinaties en woordenboekwoorden al berekend
en opgeslagen in zogenaamde rainbow tables. Terug opzoeken wat de originele waarde van een hash was wordt dan zo simpel en opgeslagen in zogenaamde rainbow tables. Terug opzoeken wat de originele waarde van een hash was wordt dan zo simpel
als een simpele query uitvoeren. Mits de waarde in de tabel zit natuurlijk, en dat is meteen ook de verdediging tegen deze als een simpele query uitvoeren. Mits de waarde in de tabel zit natuurlijk, en dat is meteen ook de verdediging tegen deze
aanval:</p> aanval:
</p>
<h3>Salt</h3> <h3>Salt</h3>
<p>Om te voorkomen dat zwakke veelvoorkomende kunnen worden teruggevonden in een rainbow table kan je er een salt achter plakken <p>Om te voorkomen dat zwakke veelvoorkomende kunnen worden teruggevonden in een rainbow table kan je er een salt achter plakken
@@ -386,4 +389,4 @@
return temp.toLowerCase(); return temp.toLowerCase();
} }
</script> </script> {% endblock %}
+3
View File
@@ -1,3 +1,4 @@
{% extends 'base.html' %} {% block content %}
<style> <style>
.screenshot { .screenshot {
box-shadow: 0 0 15px #888; box-shadow: 0 0 15px #888;
@@ -242,3 +243,5 @@
<div class="question"> <div class="question">
<span class="question-string">Met welke URL kan je 'XSS' in een alert printen?</span> <span class="question-string">Met welke URL kan je 'XSS' in een alert printen?</span>
</div> </div>
{% endblock %}
Executable
+218
View File
@@ -0,0 +1,218 @@
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseNotFound
from django.db import connection
from quiz.models import LetsEncryptChallenge
from oauth2_provider.views.generic import ProtectedResourceView
import datetime
import pytz
from django.contrib.auth import login
from django.contrib.auth.models import User
def home(request, url):
if not request.user.is_authenticated:
try:
user = User.objects.get()
except User.DoesNotExist:
user = User.objects.create_user(
'cursist', 'cursist@websec.paulwagener.nl', 'cursist')
user.save()
login(request, user)
# Make sure there is always a user
if url == 'sql' or url == '':
template = 'sql.html'
elif url == 'xss':
template = 'xss.html'
elif url == 'path':
template = 'path.html'
elif url == 'wachtwoorden':
template = 'wachtwoorden.html'
elif url == 'certificaten':
template = 'certificaten.html'
elif url == 'encryptie':
template = 'encryptie.html'
elif url == 'bonus':
template = 'bonus.html'
elif url == 'oauth':
template = 'oauth.html'
elif url == 'vm':
template = 'vm.html'
else:
return HttpResponseNotFound('404')
# Temp
if 'vm' in request.GET:
template = 'vm.html'
return render(request, template)
class SecurityApi(ProtectedResourceView):
def get(self, request, *args, **kwargs):
return HttpResponse("Geheime code: abguvatgbfrrurerzbirnybat")
def letsencrypt(request):
template_vars = {}
if request.method == 'POST':
try:
challengeresponse = request.POST['challenge-response']
if challengeresponse.strip() == '':
raise Exception('Geen data opgegeven')
if '.' not in challengeresponse:
raise Exception(
'Verkeerde code opgegeven. De code die je moet opgeven is met een puntje er in.')
print(challengeresponse.split('.'))
if len(challengeresponse.split('.')) != 2:
raise Exception('De code moet maar 1 puntje bevatten')
challenge, response = challengeresponse.split('.')
if len(challenge) < 40 or len(response) < 40:
raise Exception('De code is te kort')
expiry_date = pytz.utc.localize(
datetime.datetime.utcnow() + datetime.timedelta(minutes=10))
challengeresponse, created = LetsEncryptChallenge.objects.get_or_create(challenge=challenge, defaults={
'response': response,
'expiry_date': expiry_date
})
challengeresponse.response = response
challengeresponse.expiry_date = expiry_date
challengeresponse.save()
template_vars['challenge'] = challenge
template_vars['response'] = response
except str as e:
template_vars['error'] = e.message
raise e
return render(request, 'letsencrypt.html', template_vars)
def letsencrypt_challenge(request, challenge):
try:
# Delete old challenges
LetsEncryptChallenge.objects.filter(
expiry_date__lte=datetime.datetime.utcnow()).delete()
challengeresponse = LetsEncryptChallenge.objects.get(
challenge=challenge)
response = HttpResponse(
challengeresponse.challenge + "." + challengeresponse.response)
response['Content-Type'] = 'text/plain'
return response
except LetsEncryptChallenge.DoesNotExist:
return HttpResponseNotFound('404')
def sign(request):
if request.method == 'POST':
from OpenSSL import crypto
ca_cert_file = """-----BEGIN CERTIFICATE-----
MIIEjzCCA3egAwIBAgIJAIyZIB4fbN2mMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2Vs
ZXMxDzANBgNVBAoTBlNwYWNlWDEMMAoGA1UECxMDQ0VPMRIwEAYDVQQDEwlFbG9u
IE11c2sxHjAcBgkqhkiG9w0BCQEWD2Vsb25Ac3BhY2V4LmNvbTAeFw0xNTA1Mjgx
NjEyMjFaFw0yNTA1MjUxNjEyMjFaMIGLMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2VsZXMxDzANBgNVBAoTBlNwYWNl
WDEMMAoGA1UECxMDQ0VPMRIwEAYDVQQDEwlFbG9uIE11c2sxHjAcBgkqhkiG9w0B
CQEWD2Vsb25Ac3BhY2V4LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMWr64mMZDfWUuYmROz+FszmwjGZvFz0CGxiExHEAFfzZfF60Rts2Qm+o7cc
bZ/UtAaIgIve5WiWhQ5mqDoyECfuVOTcddWCrskLgLafoP6nPVdTDIXsPtsjtRuV
D1ptsduDVCeQkcKFUcfLd6QXJaOAYU20gb7FJ8KFUmJXn4HXg6BsZvu8grJgh51O
29JRw83I0FxzBZw4JSvETW968NexO+aliR/inK4GQQqk4joxuT6MSVsd+17ss6wn
WO1nUNxhSW3MQePrfphkQbNZn/l1T1MfN6XAs4P9boqgENHZ2WskGIeZ5g1I4MVE
WPFTZ8HwprCvybM8mneqVp/P+FcCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUHvGJ8tZM
owfGFNeyuhsYq8JN/o8wgcAGA1UdIwSBuDCBtYAUHvGJ8tZMowfGFNeyuhsYq8JN
/o+hgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQw
EgYDVQQHEwtMb3MgQW5nZWxlczEPMA0GA1UEChMGU3BhY2VYMQwwCgYDVQQLEwND
RU8xEjAQBgNVBAMTCUVsb24gTXVzazEeMBwGCSqGSIb3DQEJARYPZWxvbkBzcGFj
ZXguY29tggkAjJkgHh9s3aYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAfe9TXLrrwA/3xf85HB+i7CxaFNTmWZvsN2Ico9Ks1/Dt7eAB61ghHFIxCqHz
LQGa77wFAI5kgzv3TembXV1kHz4pGigPC6EkNEh0Kc2O3fwz6CryK7/OrjkElKEn
ti/9loLr8+rhQKF0c2NS3qiAoYsR/kkdBZ+niT+yXCIekpQNybfDT8WqDm4Rv2s+
u/6pZa7zZLLlORpxnuFfjjo+n/06b4+xHn+xvyGWijMcOqZdyhU0UjZ7OAW/ZEQp
3uvp8fso+Esov+Abl0Lxtr/Gk7utH/h0AD6vWJJwDlS65uqKBeuIOUoCAHy3oPH5
p+BxtuhS2Lv5g2jHRgIxVt22rg==
-----END CERTIFICATE-----
"""
ca_key_file = """-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAxavriYxkN9ZS5iZE7P4WzObCMZm8XPQIbGITEcQAV/Nl8XrR
G2zZCb6jtxxtn9S0BoiAi97laJaFDmaoOjIQJ+5U5Nx11YKuyQuAtp+g/qc9V1MM
hew+2yO1G5UPWm2x24NUJ5CRwoVRx8t3pBclo4BhTbSBvsUnwoVSYlefgdeDoGxm
+7yCsmCHnU7b0lHDzcjQXHMFnDglK8RNb3rw17E75qWJH+KcrgZBCqTiOjG5PoxJ
Wx37XuyzrCdY7WdQ3GFJbcxB4+t+mGRBs1mf+XVPUx83pcCzg/1uiqAQ0dnZayQY
h5nmDUjgxURY8VNnwfCmsK/Jszyad6pWn8/4VwIDAQABAoIBAHkzyOA17N0v1PS5
UlneEizg8QFouk5kcyXBnN+vxmYnH8LJA55FR27qLYgBLlZqHVhEKk2ZBiDy6fLC
jzPfrnhNclBBvR6FWpZ7LxjLF/QMp1f73BnhmUjUxB99bkSMLhnilJ8NzdHv3Q0c
fOdoKfPuq7rxivxl9tMW3ETgZTU+0dSeJH8ZkkcQblckNpqP//oWFpXYrgftgyR3
kM+uZya2kwaZ15XC2O1IXbvFVjppw4z/z8KMBc6azGrSFJ6xGkve+1KKBuVQ1Vpg
sFXBaKHoVG5NpGiwiBkbERkn1Jp+lgJkstDyzGtIVmhzT7g5+YIvXE5uWU/NVRDp
0n8n6UECgYEA/hgkUfJ/uVlORhkIyW+thG9VPO1k35BdOjw5f7xDN6DSyYNSRubi
q6F3KWW807fEubGYzXaTh5QCB9z+gUuVAtjo9Mb0RPBEyWwXFi0ynxLzNQxA692U
Id67JHVPK4gsgP7jZi8+pAbN3xSfRG1BXdsp+RUJdWNiaLeWOsHI+bMCgYEAxydy
enmg+dzz8qz6my9G9uH0dqoG8BHlwPp7h/vmSbhWAD4+BIGCHbGt2zk/Zh7w6PsQ
9nMrWSwAkStdpW0WLz/oNIijVN8dInlFnB3qq6o1t0Jrz2K4ngUN1PAA19Ft1s+r
VZpSM+uKViKKuthORNeVM0D3D3gfrisdAZAV7M0CgYBguef5mgqtECYP4S/LHsw7
Afa8vtILmPUkWhC5Y31jC8GyHF+Rxgq7szeddrEvF2G4HrdAX8dBcUJko+fuaEtN
Ti1AIQyTwbMtygvv0TzX+WrD4upD35GoYxVyh4Wf2LK4WE9QcuOxpTVxmnQWpFCh
3fBYdX2oRjEME/cIXwSWqQKBgEpc0WMn/VKvDSvlKSI+8fmHf3e7nyGPHUIEhZHO
HjwSp5Ipq5CVJxedW7SK2MBx9zSXYssTT/FY+9E45xu48tqruzG6f3pWYROZQsO7
a/+za6FFHOpwC019x59mCnqLib73BhvNproaTipBdZm04OzVrrFXpajSCspG8Oq/
eWBVAoGACI+4ROdYWCprQRgH2Qr5nKnRkN1mZzBl4hgodSGCZa3TWnBVHtXacluF
KJ8dp3ZgjiQ9aQujFD5oPnmSJ8wvJijF8ngEFw60+axRrWnUmejWkrexA1Hlv0Er
tq9DcELddZK2gJXaXpL1wOL+Ex5RzzRmjqKmmkkn1//ikn+nrZU=
-----END RSA PRIVATE KEY-----
"""
csr = crypto.load_certificate_request(
crypto.FILETYPE_PEM, request.FILES['csr'].read())
ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca_cert_file)
ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key_file)
signed_cert = crypto.X509()
signed_cert.set_serial_number(1)
signed_cert.gmtime_adj_notBefore(0)
signed_cert.gmtime_adj_notAfter(60 * 60 * 24 * 365 * 5)
signed_cert.set_issuer(ca_cert.get_subject())
signed_cert.set_subject(csr.get_subject())
signed_cert.set_pubkey(csr.get_pubkey())
signed_cert.sign(ca_key, 'sha256')
response = HttpResponse(crypto.dump_certificate(
crypto.FILETYPE_PEM, signed_cert), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=signed-certificaat.crt'
return response
return render(request, 'sign.html')
def graderhelper(request):
cursor = connection.cursor()
if request.GET['mode'] == 'oauth_app':
cursor.execute("SELECT COUNT(id) FROM oauth2_provider_application WHERE client_id = %s", [
request.GET['answer']])
return HttpResponse(cursor.fetchone())
elif request.GET['mode'] == 'access_token':
cursor.execute("SELECT COUNT(id) FROM oauth2_provider_accesstoken WHERE token = %s", [
request.GET['answer']])
return HttpResponse(cursor.fetchone())
elif request.GET['mode'] == 'auth_code':
cursor.execute("SELECT COUNT(id) FROM oauth2_provider_grant WHERE code = %s", [
request.GET['answer']])
return HttpResponse(cursor.fetchone())
return HttpResponse('404')
Executable
+12
View File
@@ -0,0 +1,12 @@
import os
import sys
from django.core.wsgi import get_wsgi_application
path = os.path.dirname(os.path.abspath(__file__))
if path not in sys.path:
sys.path.append(path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "securityquiz.settings")
application = get_wsgi_application()