Skip to content
This repository was archived by the owner on Mar 15, 2021. It is now read-only.

Commit fe8b8d5

Browse files
author
y0no
committed
Add attachments to landing_page model
Add an attachment download page Add jinja support for landing_page render Add get_template_context function who transform get_template_vars return into a Django context (for Jinja2 rendering) Add new tracker strings
1 parent 6a88f98 commit fe8b8d5

File tree

6 files changed

+91
-11
lines changed

6 files changed

+91
-11
lines changed

phishing/helpers.py

+39-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from django.core.mail import EmailMultiAlternatives
99
from django.core.mail.backends.smtp import EmailBackend
1010
from django.core.urlresolvers import reverse
11+
from django.template import Context
1112
from django.template.loader import render_to_string
1213
from django.utils.translation import ugettext_lazy as _
1314
from pyshorteners import Shortener
@@ -16,7 +17,8 @@
1617
from phishing.signals import send_email, make_template_vars
1718
from phishing.strings import TRACKER_LANDING_PAGE_OPEN, \
1819
TRACKER_LANDING_PAGE_POST, POST_TRACKER_ID, TRACKER_EMAIL_OPEN, \
19-
TRACKER_EMAIL_SEND, POST_DOMAIN, TRACKER_ATTACHMENT_EXECUTED
20+
TRACKER_EMAIL_SEND, POST_DOMAIN, TRACKER_ATTACHMENT_EXECUTED, \
21+
TRACKER_LANDING_ATTACHMENT_DOWNLOADED
2022
from .models import EmailTemplate, Target, Tracker
2123

2224

@@ -44,7 +46,17 @@ def clone_url(url):
4446
return html
4547

4648

47-
def get_template_vars(campaign=None, target=None, email_template=None):
49+
def get_template_context(campaign=None, target=None, email_template=None,
50+
attachments=None):
51+
vars = get_template_vars(campaign, target, email_template, attachments)
52+
ctx = {}
53+
for var in vars:
54+
ctx[var['name']] = var['value']
55+
return Context(ctx)
56+
57+
58+
def get_template_vars(campaign=None, target=None, email_template=None,
59+
attachments=None,):
4860
"""Get template variable infos.
4961
5062
:param campaign: `.models.Campaign`
@@ -55,6 +67,7 @@ def get_template_vars(campaign=None, target=None, email_template=None):
5567

5668
landing_page_url = ''
5769

70+
5871
# has landing page ?
5972
if email_template and email_template.landing_page:
6073
tracker = Tracker.objects.filter(
@@ -113,9 +126,28 @@ def get_template_vars(campaign=None, target=None, email_template=None):
113126
'name': 'landing_page_url',
114127
'description': _('Url of landing page'),
115128
'value': landing_page_url,
116-
}
129+
},
117130
]
118131

132+
# If there is attachments, we add it to the varables list
133+
if attachments:
134+
for id, attachment in enumerate(attachments):
135+
tracker = Tracker.objects.filter(
136+
campaign=campaign,
137+
target=target,
138+
key=TRACKER_LANDING_ATTACHMENT_DOWNLOADED % (id+1)
139+
).first()
140+
url = ''
141+
if tracker:
142+
url = reverse('attachment_download', args=(attachment.pk,
143+
tracker.pk))
144+
145+
vars_data.append({
146+
'name': 'attachment_%d_url' % (id+1),
147+
'description': 'Attachment URL for "%s"' % attachment.name,
148+
'value': url,
149+
})
150+
119151
make_template_vars.send(sender=EmailTemplate, vars_data=vars_data,
120152
campaign=campaign, target=target,
121153
email_template=email_template)
@@ -332,6 +364,10 @@ def replace_vars(content):
332364
if POST_TRACKER_ID in landing_page.html:
333365
add_tracker(TRACKER_LANDING_PAGE_POST, 'no', 0)
334366

367+
for id, attachment in enumerate(landing_page.attachments.all()):
368+
add_tracker(TRACKER_LANDING_ATTACHMENT_DOWNLOADED % (id+1),
369+
'not downloaded', 0)
370+
335371
mail = EmailMultiAlternatives(
336372
subject=replace_vars(target_email.email_subject),
337373
body=replace_vars(target_email.text_content),

phishing/models/landing_page.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from django.db.models import CharField, Model, TextField, URLField
1+
from django.db.models import CharField, Model, TextField, URLField, \
2+
ManyToManyField
23
from django.db.models.signals import pre_save
34
from django.dispatch import receiver
45
from django.utils.translation import ugettext_lazy as _
@@ -15,6 +16,9 @@ class LandingPage(Model):
1516
name = CharField(_('Landing page name'), max_length=256, unique=True)
1617
domain = URLField(_('Domain to use'), blank=True)
1718
html = TextField(_('HTML source code'))
19+
attachments = ManyToManyField('Attachment',
20+
related_name='landingpage_attachment',
21+
blank=True)
1822

1923
def __str__(self):
2024
"""

phishing/strings.py

+3
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@
1010
TRACKER_LANDING_PAGE_OPEN = 'landing_page_open'
1111
TRACKER_LANDING_PAGE_POST = 'landing_page_post'
1212

13+
TRACKER_LANDING_ATTACHMENT_DOWNLOADED = 'lp_attachment_%s_dl'
14+
TRACKER_LANDING_ATTACHMENT_EXECUTED = 'lp_attachment_%s_exec'
15+
1316
TRACKER_ATTACHMENT_EXECUTED = 'attachment_executed'

phishing/urls.py

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
attachment.UpdateAttachment.as_view(), name='attachment_edit'),
2828
url(r'^attachments/delete/(?P<pk>\d+)/$',
2929
attachment.DeleteAttachment.as_view(), name='attachment_delete'),
30+
url(r'^attachments/(?P<attachment_id>\d+)/(?P<tracker_id>[0-9a-z-]+)$',
31+
attachment.download, name='attachment_download'),
3032

3133
# landing page
3234
url(r'^landing-page/$', landing_page.List.as_view(),

phishing/views/attachment.py

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from django.contrib.auth.mixins import PermissionRequiredMixin
2+
from django.http import HttpResponse
3+
from django.shortcuts import get_object_or_404
24
from django.urls import reverse_lazy
35
from django.views.generic import CreateView
46
from django.views.generic import DeleteView
57
from django.views.generic import ListView
68
from django.views.generic import UpdateView
79

8-
from phishing.models import Attachment
10+
from phishing.models import Attachment, Tracker, TrackerInfos
911

1012

1113
class CreateAttachment(PermissionRequiredMixin, CreateView):
@@ -34,3 +36,26 @@ class ListAttachment(PermissionRequiredMixin, ListView):
3436

3537
permission_required = 'view_emailtemplate'
3638
model = Attachment
39+
40+
41+
def download(request, attachment_id, tracker_id):
42+
# add infos
43+
tracker = get_object_or_404(Tracker, pk=tracker_id)
44+
infos = TrackerInfos.create(target_tracker=tracker,
45+
http_request=request)
46+
count = TrackerInfos.objects.filter(target_tracker=tracker).count()
47+
48+
# update values
49+
tracker.value = 'downloaded'
50+
tracker.infos = count
51+
tracker.save()
52+
53+
54+
attachment = get_object_or_404(Attachment, pk=attachment_id)
55+
attachment_file = attachment.build(tracker_id)
56+
response = HttpResponse(attachment_file,
57+
content_type='application/force-download')
58+
response['Content-Disposition']= 'attachment; filename=%s' % \
59+
attachment.attachment_name
60+
return response
61+

phishing/views/landing_page.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@
77
from django.http import HttpResponse, HttpResponseBadRequest, \
88
HttpResponseRedirect
99
from django.shortcuts import get_object_or_404, render
10+
from django.template import Template
1011
from django.template.loader import render_to_string
1112
from django.views.decorators.csrf import csrf_exempt
1213
from django.views.generic import DeleteView, UpdateView, CreateView, ListView
1314

1415
from mercure import settings
15-
from phishing.helpers import clone_url, get_template_vars, intercept_html_post
16+
from phishing.helpers import clone_url, get_template_vars, intercept_html_post, \
17+
get_template_context
1618
from phishing.models import LandingPage, Tracker, TrackerInfos
1719
from phishing.strings import TRACKER_LANDING_PAGE_POST, POST_TRACKER_ID, \
1820
POST_DOMAIN
1921
from phishing.signals import landing_page_printed
2022

2123

24+
2225
@permission_required('add_landingpage')
2326
def clone(request):
2427
"""Use to clone the html of any page."""
@@ -39,20 +42,25 @@ class Create(LoginRequiredMixin, CreateView):
3942
"""Use to create landing page."""
4043
model = LandingPage
4144
success_url = reverse_lazy('landing_page_list')
42-
fields = ('name', 'domain', 'html')
45+
fields = ('name', 'domain', 'attachments', 'html')
4346

4447
def get_context_data(self, **kwargs):
4548
ctx = super(Create, self).get_context_data(**kwargs)
4649

4750
# add vars infos
4851
ctx['template_vars'] = get_template_vars()
49-
5052
return ctx
5153

5254

5355
class Edit(Create, UpdateView):
5456
"""Use to edit landing page."""
55-
pass
57+
def get_context_data(self, **kwargs):
58+
ctx = super(Edit, self).get_context_data(**kwargs)
59+
60+
61+
ctx['template_vars'] = get_template_vars(
62+
attachments=self.object.attachments.all())
63+
return ctx
5664

5765

5866
class Delete(PermissionRequiredMixin, DeleteView):
@@ -88,8 +96,10 @@ def landing_page(request, tracker_id):
8896
html = landing_page.html
8997
target = tracker.target
9098

91-
for var in get_template_vars(campaign, target, email_template):
92-
html = html.replace(var['name'], var['value'] or '')
99+
tpl = Template(html)
100+
ctx = get_template_context(campaign, target, email_template,
101+
landing_page.attachments.all())
102+
html = tpl.render(ctx)
93103

94104
# add navigator info script
95105
navigator_info = render_to_string(

0 commit comments

Comments
 (0)