Compléter la console (sauf pour l’attaquant)
La console est quasiment prête : il ne reste plus qu’à faire le côté de l’attaquant.
This commit is contained in:
parent
23409b4d6f
commit
662f0668a3
|
@ -9,11 +9,13 @@ template: "template_toolkit"
|
||||||
# Specify the addresses of the API endpoints for the other components of the
|
# Specify the addresses of the API endpoints for the other components of the
|
||||||
# system
|
# system
|
||||||
api:
|
api:
|
||||||
dns: "ns.example:3000"
|
dns: "172.31.0.53:3000"
|
||||||
|
sender: "172.31.10.1:3000"
|
||||||
|
recipient: "172.31.20.1:3000"
|
||||||
|
attacker: "172.31.30.1:3000"
|
||||||
|
|
||||||
# Lists the DNS zones that can be edited by the user
|
# Lists the DNS zones that can be edited by the user
|
||||||
editable_zones:
|
editable_zones:
|
||||||
- example
|
|
||||||
- expediteur.example
|
- expediteur.example
|
||||||
- destinataire.example
|
- destinataire.example
|
||||||
- attaquant.example
|
- attaquant.example
|
||||||
|
|
|
@ -50,11 +50,8 @@ get '/dns/zone-edit/:zone' => sub {
|
||||||
my $zone_contents;
|
my $zone_contents;
|
||||||
|
|
||||||
if (defined $zone) {
|
if (defined $zone) {
|
||||||
my $client = REST::Client->new();
|
my ($response, $status) = call_api(GET => 'dns', "/zone/${zone}/file");
|
||||||
$client->setHost(config->{'api'}{'dns'});
|
$zone_contents = $response->{contents};
|
||||||
$client->GET("/zone/${zone}/file");
|
|
||||||
my $response = from_json($client->responseContent());
|
|
||||||
$zone_contents = $response->{'contents'};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template 'dns/zone-edit' => {
|
template 'dns/zone-edit' => {
|
||||||
|
@ -71,25 +68,75 @@ post '/dns/zone-edit/:zone' => sub {
|
||||||
}
|
}
|
||||||
|
|
||||||
my $contents = body_parameters->{'zone-contents'};
|
my $contents = body_parameters->{'zone-contents'};
|
||||||
|
my (undef, $status) = call_api(PUT => 'dns', "/zone/${zone}/file", { contents => $contents });
|
||||||
my $client = REST::Client->new();
|
my $success = ($status eq '200') ? 'success' : 'failure';
|
||||||
$client->setHost(config->{'api'}{'dns'});
|
|
||||||
$client->PUT("/zone/${zone}/file",
|
|
||||||
encode_json({ contents => $contents }),
|
|
||||||
{
|
|
||||||
"Content-Type" => "application/json",
|
|
||||||
"Accept" => "application/json"
|
|
||||||
});
|
|
||||||
|
|
||||||
my $success;
|
|
||||||
if ($client->responseCode() eq '200') {
|
|
||||||
$success = 'success';
|
|
||||||
} else {
|
|
||||||
warn "Got " . $client->responseCode() . " from upstream: " . $client->responseContent();
|
|
||||||
$success = 'failure'
|
|
||||||
}
|
|
||||||
|
|
||||||
redirect "/dns/zone-edit/$zone?success=$success", 303;
|
redirect "/dns/zone-edit/$zone?success=$success", 303;
|
||||||
|
};
|
||||||
|
|
||||||
|
get '/sender/dkim-keys' => sub {
|
||||||
|
my ($installed_keys, $status) = call_api(GET => 'sender', '/installed-keys');
|
||||||
|
($status eq '200') or die "API returned $status";
|
||||||
|
|
||||||
|
template 'sender/dkim-keys' => {
|
||||||
|
active_role => 'sender',
|
||||||
|
title => 'Gestion des clefs DKIM',
|
||||||
|
installed_keys => $installed_keys,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
get '/dkim-generator/sender' => sub {
|
||||||
|
template 'dkim-generator/sender' => {
|
||||||
|
title => 'Générateur de clefs DKIM'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
post '/dkim-generator/sender' => sub {
|
||||||
|
my $api_params = {
|
||||||
|
domain => body_parameters->get('domain'),
|
||||||
|
selector => body_parameters->get('selector'),
|
||||||
|
key_size => body_parameters->get('key-size')
|
||||||
|
};
|
||||||
|
|
||||||
|
my ($response, $status) = call_api(POST => 'sender', '/generate-dkim-key', $api_params);
|
||||||
|
($status eq 200) or die "API returned $status";
|
||||||
|
|
||||||
|
template 'dkim-generator/sender' => {
|
||||||
|
title => 'Générateur de clefs DKIM',
|
||||||
|
txt_record => $response->{'txt_record'}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
get '/attacker/spoof' => sub {
|
||||||
|
template 'attacker/spoof' => {
|
||||||
|
title => 'Usurpateur d’identité de courriel'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
get '/sender/send-email' => sub {
|
||||||
|
my %template_params = (
|
||||||
|
title => 'Envoi de messages légitimes',
|
||||||
|
email_data => [
|
||||||
|
{
|
||||||
|
what => 'Confirmation de commande',
|
||||||
|
from => 'support@expediteur.example',
|
||||||
|
url => 'confirmation_email'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
what => 'Newsletter',
|
||||||
|
from => 'info@newsletter.expediteur.example',
|
||||||
|
url => 'newsletter'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
my $success = query_parameters->get('success');
|
||||||
|
if (defined $success) {
|
||||||
|
$template_params{success} = ($success eq 'success') ? 'success' : 'failure';
|
||||||
|
}
|
||||||
|
template 'sender/send-email' => \%template_params;
|
||||||
|
};
|
||||||
|
|
||||||
get '/recipient/settings' => sub {
|
get '/recipient/settings' => sub {
|
||||||
my ($system_status, $http_code) = call_api(GET => 'recipient', '/status');
|
my ($system_status, $http_code) = call_api(GET => 'recipient', '/status');
|
||||||
die if $http_code ne '200';
|
die if $http_code ne '200';
|
||||||
|
@ -110,6 +157,13 @@ post '/recipient/settings' => sub {
|
||||||
redirect "/recipient/settings?success=$success", 303;
|
redirect "/recipient/settings?success=$success", 303;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
get '/sender/send-email/:email' => sub {
|
||||||
|
my $email = route_parameters->get('email');
|
||||||
|
|
||||||
|
my (undef, $response) = call_api(POST => 'sender', "/send-email/${email}");
|
||||||
|
my $success = ($response =~ /^2\d\d$/) ? 'success' : 'failure';
|
||||||
|
|
||||||
|
redirect "/sender/send-email?success=$success", 303;
|
||||||
};
|
};
|
||||||
|
|
||||||
get '/recipient/webmail' => sub {
|
get '/recipient/webmail' => sub {
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
<div class="container">
|
||||||
<h1>Erreur 404</h1>
|
<h1>Erreur 404</h1>
|
||||||
<h2>Page non trouvée</h2>
|
<h2>Page non trouvée</h2>
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
TODO
|
|
@ -0,0 +1,50 @@
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1>Génération de clef DKIM</h1>
|
||||||
|
<form method="POST" class="mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="domain" class="form-label">Domaine</label>
|
||||||
|
<input type="text" name="domain" class="form-control" value="expediteur.example" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="selector" class="form-label">Sélecteur</label>
|
||||||
|
<input type="text" name="selector" class="form-control" value="default" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="key-size" class="form-label">Taille de la clef</label>
|
||||||
|
<select class="form-select" id="key-size" name="key-size">
|
||||||
|
<option value="1024">1 024 bits</option>
|
||||||
|
<option value="2048" selected>2 048 bits</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Générer</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
[% IF txt_record %]
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<p>Clef générée.</p>
|
||||||
|
<p>Publiez ensuite la clef publique dans la <a href="[% request.uri_base %]/dns/zone-edit/expediteur.example">zone DNS</a> :</p>
|
||||||
|
<div class="card text-bg-success">
|
||||||
|
<div class="card-header text-end">
|
||||||
|
<button id="copy-button" class="btn btn-light" onClick="copyTxtRR()">Copier</button>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<pre class="card-text"><code id="txt-record">[% txt_record | html %]</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function copyTxtRR() {
|
||||||
|
navigator.clipboard.writeText($("#txt-record").text());
|
||||||
|
$("#copy-button").text("Texte copié");
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,41 @@
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<h1>Liste des clefs DKIM installées sur le système</h1>
|
||||||
|
[% FOR installed_keys %]
|
||||||
|
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-3">
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">[% domain | html %]</h5>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<li class="list-group-item">
|
||||||
|
Sélecteur actuel :
|
||||||
|
[% IF current_key %][% current_key | html %][% ELSE %](aucun)[% END %]
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
Sélecteurs disponibles :
|
||||||
|
<ul>
|
||||||
|
[% FOR selector IN available_keys -%]
|
||||||
|
<li>
|
||||||
|
[%- IF selector == current_key -%]
|
||||||
|
<strong>[% selector | html %]</strong>
|
||||||
|
[%- ELSE -%]
|
||||||
|
[% selector | html %]
|
||||||
|
[%- END -%]
|
||||||
|
</li>
|
||||||
|
[% END %]
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
[% END %]
|
||||||
|
[% UNLESS installed_keys.size %]
|
||||||
|
<p>
|
||||||
|
Aucune clef DKIM n’est active sur le système. Commencez par <a href="[% request.uri_base %]/dkim-generator/sender">en générer une</a>.
|
||||||
|
</p>
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<div class="container">
|
||||||
|
[% IF success == 'success' %]
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<p>Le courriel a bien été envoyé.</p>
|
||||||
|
<a class="btn btn-outline-success" href="[% request.uri_base %]/recipient/webmail">Relever les courriels du destinataire</a>
|
||||||
|
</div>
|
||||||
|
[% ELSIF success == 'failure' %]
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
Une erreur est survenue lors de l’envoi du courriel.
|
||||||
|
</div>
|
||||||
|
[% END %]
|
||||||
|
<h1>Système d’e-mailing</h1>
|
||||||
|
<div class="row mt-3">
|
||||||
|
[% FOR email_data %]
|
||||||
|
<div class="col-sm-12 col-md-12 col-lg-6 col-xl-4 mb-3">
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">[% what | html %]</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">
|
||||||
|
Expéditeur : [% from | html %]
|
||||||
|
</p>
|
||||||
|
<a href="[% request.uri_base %]/sender/send-email/[% url | html %]" class="btn btn-secondary">Envoyer</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
[% END %]
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in New Issue