diff --git a/phishing/helpers.py b/phishing/helpers.py index e3a4720..fa6e285 100644 --- a/phishing/helpers.py +++ b/phishing/helpers.py @@ -8,6 +8,7 @@ from django.core.mail import EmailMultiAlternatives from django.core.mail.backends.smtp import EmailBackend from django.core.urlresolvers import reverse +from django.template import Context from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ from pyshorteners import Shortener @@ -16,7 +17,8 @@ from phishing.signals import send_email, make_template_vars from phishing.strings import TRACKER_LANDING_PAGE_OPEN, \ TRACKER_LANDING_PAGE_POST, POST_TRACKER_ID, TRACKER_EMAIL_OPEN, \ - TRACKER_EMAIL_SEND, POST_DOMAIN, TRACKER_ATTACHMENT_EXECUTED + TRACKER_EMAIL_SEND, POST_DOMAIN, TRACKER_ATTACHMENT_EXECUTED, \ + TRACKER_LANDING_ATTACHMENT_DOWNLOADED from .models import EmailTemplate, Target, Tracker @@ -44,7 +46,17 @@ def clone_url(url): return html -def get_template_vars(campaign=None, target=None, email_template=None): +def get_template_context(campaign=None, target=None, email_template=None, + attachments=None): + vars = get_template_vars(campaign, target, email_template, attachments) + ctx = {} + for var in vars: + ctx[var['name']] = var['value'] + return Context(ctx) + + +def get_template_vars(campaign=None, target=None, email_template=None, + attachments=None,): """Get template variable infos. :param campaign: `.models.Campaign` @@ -55,6 +67,7 @@ def get_template_vars(campaign=None, target=None, email_template=None): landing_page_url = '' + # has landing page ? if email_template and email_template.landing_page: tracker = Tracker.objects.filter( @@ -113,9 +126,28 @@ def get_template_vars(campaign=None, target=None, email_template=None): 'name': 'landing_page_url', 'description': _('Url of landing page'), 'value': landing_page_url, - } + }, ] + # If there is attachments, we add it to the varables list + if attachments: + for id, attachment in enumerate(attachments): + tracker = Tracker.objects.filter( + campaign=campaign, + target=target, + key=TRACKER_LANDING_ATTACHMENT_DOWNLOADED % (id+1) + ).first() + url = '' + if tracker: + url = reverse('attachment_download', args=(attachment.pk, + tracker.pk)) + + vars_data.append({ + 'name': 'attachment_%d_url' % (id+1), + 'description': 'Attachment URL for "%s"' % attachment.name, + 'value': url, + }) + make_template_vars.send(sender=EmailTemplate, vars_data=vars_data, campaign=campaign, target=target, email_template=email_template) @@ -332,6 +364,10 @@ def replace_vars(content): if POST_TRACKER_ID in landing_page.html: add_tracker(TRACKER_LANDING_PAGE_POST, 'no', 0) + for id, attachment in enumerate(landing_page.attachments.all()): + add_tracker(TRACKER_LANDING_ATTACHMENT_DOWNLOADED % (id+1), + 'not downloaded', 0) + mail = EmailMultiAlternatives( subject=replace_vars(target_email.email_subject), body=replace_vars(target_email.text_content), diff --git a/phishing/models/landing_page.py b/phishing/models/landing_page.py index 470bd91..8a600bd 100644 --- a/phishing/models/landing_page.py +++ b/phishing/models/landing_page.py @@ -1,4 +1,5 @@ -from django.db.models import CharField, Model, TextField, URLField +from django.db.models import CharField, Model, TextField, URLField, \ + ManyToManyField from django.db.models.signals import pre_save from django.dispatch import receiver from django.utils.translation import ugettext_lazy as _ @@ -15,6 +16,9 @@ class LandingPage(Model): name = CharField(_('Landing page name'), max_length=256, unique=True) domain = URLField(_('Domain to use'), blank=True) html = TextField(_('HTML source code')) + attachments = ManyToManyField('Attachment', + related_name='landingpage_attachment', + blank=True) def __str__(self): """ diff --git a/phishing/strings.py b/phishing/strings.py index 4d53a5b..a288bc2 100644 --- a/phishing/strings.py +++ b/phishing/strings.py @@ -10,4 +10,7 @@ TRACKER_LANDING_PAGE_OPEN = 'landing_page_open' TRACKER_LANDING_PAGE_POST = 'landing_page_post' +TRACKER_LANDING_ATTACHMENT_DOWNLOADED = 'lp_attachment_%s_dl' +TRACKER_LANDING_ATTACHMENT_EXECUTED = 'lp_attachment_%s_exec' + TRACKER_ATTACHMENT_EXECUTED = 'attachment_executed' diff --git a/phishing/urls.py b/phishing/urls.py index 725110b..0507a99 100644 --- a/phishing/urls.py +++ b/phishing/urls.py @@ -27,6 +27,8 @@ attachment.UpdateAttachment.as_view(), name='attachment_edit'), url(r'^attachments/delete/(?P\d+)/$', attachment.DeleteAttachment.as_view(), name='attachment_delete'), + url(r'^attachments/(?P\d+)/(?P[0-9a-z-]+)$', + attachment.download, name='attachment_download'), # landing page url(r'^landing-page/$', landing_page.List.as_view(), diff --git a/phishing/views/attachment.py b/phishing/views/attachment.py index 844701a..1606cb2 100644 --- a/phishing/views/attachment.py +++ b/phishing/views/attachment.py @@ -1,11 +1,13 @@ from django.contrib.auth.mixins import PermissionRequiredMixin +from django.http import HttpResponse +from django.shortcuts import get_object_or_404 from django.urls import reverse_lazy from django.views.generic import CreateView from django.views.generic import DeleteView from django.views.generic import ListView from django.views.generic import UpdateView -from phishing.models import Attachment +from phishing.models import Attachment, Tracker, TrackerInfos class CreateAttachment(PermissionRequiredMixin, CreateView): @@ -34,3 +36,26 @@ class ListAttachment(PermissionRequiredMixin, ListView): permission_required = 'view_emailtemplate' model = Attachment + + +def download(request, attachment_id, tracker_id): + # add infos + tracker = get_object_or_404(Tracker, pk=tracker_id) + infos = TrackerInfos.create(target_tracker=tracker, + http_request=request) + count = TrackerInfos.objects.filter(target_tracker=tracker).count() + + # update values + tracker.value = 'downloaded' + tracker.infos = count + tracker.save() + + + attachment = get_object_or_404(Attachment, pk=attachment_id) + attachment_file = attachment.build(tracker_id) + response = HttpResponse(attachment_file, + content_type='application/force-download') + response['Content-Disposition']= 'attachment; filename=%s' % \ + attachment.attachment_name + return response + diff --git a/phishing/views/landing_page.py b/phishing/views/landing_page.py index 1aa855e..da3f0f1 100644 --- a/phishing/views/landing_page.py +++ b/phishing/views/landing_page.py @@ -7,18 +7,21 @@ from django.http import HttpResponse, HttpResponseBadRequest, \ HttpResponseRedirect from django.shortcuts import get_object_or_404, render +from django.template import Template from django.template.loader import render_to_string from django.views.decorators.csrf import csrf_exempt from django.views.generic import DeleteView, UpdateView, CreateView, ListView from mercure import settings -from phishing.helpers import clone_url, get_template_vars, intercept_html_post +from phishing.helpers import clone_url, get_template_vars, intercept_html_post, \ + get_template_context from phishing.models import LandingPage, Tracker, TrackerInfos from phishing.strings import TRACKER_LANDING_PAGE_POST, POST_TRACKER_ID, \ POST_DOMAIN from phishing.signals import landing_page_printed + @permission_required('add_landingpage') def clone(request): """Use to clone the html of any page.""" @@ -39,20 +42,25 @@ class Create(LoginRequiredMixin, CreateView): """Use to create landing page.""" model = LandingPage success_url = reverse_lazy('landing_page_list') - fields = ('name', 'domain', 'html') + fields = ('name', 'domain', 'attachments', 'html') def get_context_data(self, **kwargs): ctx = super(Create, self).get_context_data(**kwargs) # add vars infos ctx['template_vars'] = get_template_vars() - return ctx class Edit(Create, UpdateView): """Use to edit landing page.""" - pass + def get_context_data(self, **kwargs): + ctx = super(Edit, self).get_context_data(**kwargs) + + + ctx['template_vars'] = get_template_vars( + attachments=self.object.attachments.all()) + return ctx class Delete(PermissionRequiredMixin, DeleteView): @@ -88,8 +96,10 @@ def landing_page(request, tracker_id): html = landing_page.html target = tracker.target - for var in get_template_vars(campaign, target, email_template): - html = html.replace(var['name'], var['value'] or '') + tpl = Template(html) + ctx = get_template_context(campaign, target, email_template, + landing_page.attachments.all()) + html = tpl.render(ctx) # add navigator info script navigator_info = render_to_string(