Skip to content

Instantly share code, notes, and snippets.

@blark
Created December 14, 2015 22:25
Show Gist options
  • Save blark/381a0e2672747ca0f205 to your computer and use it in GitHub Desktop.
Save blark/381a0e2672747ca0f205 to your computer and use it in GitHub Desktop.
Phishing with iPython Notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Phishing with Amazon SES\n",
"\n",
"This iPython notebook was created to make phishing campaigns a little less painful. We use AWS, in particular Simple Email Service to send our phishing campaign. \n",
"\n",
"Stuff you need to take care of OR warning: this script doesn't do it all:\n",
"\n",
"1. Go register a domain and set up email like the pro you are. Make sure it all works. \n",
"1. You have set up your own phishing web site complete with appropriate logging so you can capture visits. Any and all features you want (eg. save submitted usernames and passwords) must be implemented by YOU. See [notes](#notes) for help!\n",
"1. You have crafted [an HTML email](#email) that works properly when rendered (likely in Outlook... which can be a pain). Hint: use the test feature of this script and tweak the email accordingly. You can craft and test the email in this notebook now too, or build it externally using some other editor and then just load it. \n",
"1. You have the Unix CLI fu (or Python fu) to assemble statistics on clicks yourself."
]
},
{
"cell_type": "code",
"execution_count": 144,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from email.mime.multipart import MIMEMultipart\n",
"from email.mime.text import MIMEText\n",
"from email.mime.image import MIMEImage\n",
"from itertools import cycle, izip\n",
"from IPython.display import Image, HTML, display\n",
"from ipywidgets import widgets, interact, interactive, fixed\n",
"from bs4 import BeautifulSoup\n",
"import markdown2\n",
"import pandas as pd\n",
"import boto.ses\n",
"import os"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Amazon Setup.\n",
"You'll need to get these from Amazon Web Services (AWS): "
]
},
{
"cell_type": "code",
"execution_count": 145,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"aws_zone='us-east-1'\n",
"aws_id='YOUR_ID_HERE'\n",
"aws_secret='YOUR_SECRET_HERE'\n",
"\n",
"# Create the SES connection object\n",
"conn = boto.ses.connect_to_region(aws_zone, aws_access_key_id=aws_id, aws_secret_access_key=aws_secret)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Phish Configuration\n",
"Provide the following configuration information for the phishing campaign:\n",
"\n",
"- **email_list**: The location of the Excel file containing phishing target information. Format is first, last, email\n",
"- **msg_subject**: The subject line of the phishing email.\n",
"- **msg_from**: The from address format is: `Name <email@domain.com>`\n",
"- **phish_url**: The base URL for phishing (a unique ID will based on email address will be appended.\n",
"- **test_email**: The email address to use for sending tests of the phishing campaign.\n",
"- **html_file**: The location of a file containing the html formatted email, use {{phish}} to insert phishing URL and {{firstName}} to insert the target's firstname.\n",
"- **img_file**: The location of image file(s) to be read and added as a MIME attachments. "
]
},
{
"cell_type": "code",
"execution_count": 146,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# example DOS style path: C:\\\\Users\\\\username\\\\Documents\\\\Test\\\\targets.xlsx\n",
"\n",
"email_list = 'C:\\\\Users\\\\blark\\\\Documents\\\\Test\\\\dummy.xlsx'\n",
"msg_subject = 'This is the message subject'\n",
"msg_from = 'derp@herp.com'\n",
"phish_url = 'https://www.secure-company.com'\n",
"test_email = 'your@email.com'\n",
"img_files = [] # don't forget to use two \\\\ for DOS style paths."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Read image files and convert them to MIME attachments.\n",
"\n",
"This loop will read the images, and convert them to MIME and then display them with a label for your reference. \n",
"\n",
"Insert these files into your HTML template using an image tag like so: `<img src=\"cid:image1\">`\n"
]
},
{
"cell_type": "code",
"execution_count": 147,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [],
"source": [
"msg_img = []\n",
"\n",
"for idx, f in enumerate(img_files):\n",
" img = open(f, 'rb').read()\n",
" msg_img.insert(idx, MIMEImage(img, name=os.path.basename(f)))\n",
" msg_img[idx].add_header('Content-ID', '<image%s>' % idx)\n",
" display('<Image' + str(idx) + '>', Image(img))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Email Body\n",
"\n",
"<a id=\"email\"></a>\n",
"\n",
"If you want to edit the body in browser you can simply enter it here. This field is prepopulated with Lorum Ipsum for demonstration purposes. \n",
"\n",
"Thanks to the markdown2 module you can use [markdown syntax](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) to make things more readable, and when that's not powerful enough you can switch to inline HTML."
]
},
{
"cell_type": "code",
"execution_count": 148,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [],
"source": [
"# This will be added to all <p> elements for your convenience.\n",
"# Unless there is already a style tag, then you're on your own. \n",
"BODY_STYLE = \"font-family:sans-serif;\"\n",
"\n",
"# **********************************************************************************\n",
"\n",
"email_body = \"\"\"\n",
"Dear {{firstName}},\n",
"\n",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua [Link Test]({{phish}}).\n",
"\n",
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n",
"\n",
"Praesent non turpis lacus. Aenean hendrerit dui justo, a euismod mi luctus ac. Morbi sed tortor vel ante tempor pulvinar. Ut mattis est nisl, ac placerat arcu tincidunt non. Donec condimentum molestie tempus. Suspendisse condimentum feugiat leo dapibus viverra. Sed nec porttitor augue, nec varius augue. Phasellus enim justo, molestie vehicula dictum vel, convallis id diam. \n",
"\"\"\"\n",
"\n",
"# **********************************************************************************\n",
"#\n",
"# Convert markdown to HTML, add some style with BeautifulSoup\n",
"#\n",
"html_body = markdown2.markdown(email_body)\n",
"\n",
"html_body = BeautifulSoup(html_body) \n",
"# strip all the tags and store text only for later\n",
"text_body = html_body.getText()\n",
"# add some style to the paragraph elements\n",
"for p_tag in html_body.find_all('p'):\n",
" if p_tag.has_attr('style'):\n",
" pass\n",
" else:\n",
" p_tag['style'] = BODY_STYLE\n",
" \n",
"html_body = html_body.prettify(\"utf-8\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Email Signature\n",
"\n",
"This is where things get dicey. Companies like their fancy signatures that have all kinds of images and shit, they can be hard to emulate. Godspeed. \n",
"\n",
"Usually this is where you want to insert your images, do so using markdown like so: `![Alt Text](cid:image0)`\n",
"\n",
"**Note:** if you want to avoid designing the email in the iPython Notebook you can do it all outside and just read the file in using the last line of the following cell that is commented out. Be sure to delete all this other cruft if you do that. "
]
},
{
"cell_type": "code",
"execution_count": 149,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"SIG_STYLE = 'font-family:sans-serif;'\n",
"\n",
"# **********************************************************************************\n",
"\n",
"email_sig = \"\"\"\n",
"-- \n",
"**IT Helpdesk** \n",
"[helpdesk@secure-company.com](mailto:helpdesk@secure-company.com) \n",
"\n",
"T: (888)PHI-SHME \n",
"A: 123 Derp St., Suite 1000 | Anytown, ON | H0H 0H0 \n",
"[http://www.company.com](http://www.company.com) \n",
"![Image Examle](cid:image0)\n",
"___\n",
"<table style=\"margin-top: 1em;border-collapse:collapse;\"><tbody>\n",
"<tr>\n",
"<td>\n",
"Inline HTML table\n",
"</td>\n",
"<td style=\"padding-left:10px\"><p>Some stupid disclaimer notice here.</p>\n",
"</tr>\n",
"</tbody></table>\n",
"\"\"\"\n",
"\n",
"# **********************************************************************************\n",
"#\n",
"# Convert markdown to HTML and add style \n",
"#\n",
"html_sig = markdown2.markdown(email_sig)\n",
"\n",
"html_sig = BeautifulSoup(html_sig)\n",
"# strip all the tags and store text only for later\n",
"text_sig = html_sig.getText()\n",
"\n",
"# you can do other customizations here if you need to, example:\n",
"# this is pretty derpy, I should probably build a markdown extension for this...\n",
"#for img_tag in html_sig.find_all('img'):\n",
"# img_tag['style'] = 'float:left'\n",
"for p_tag in html_sig.find_all('p'):\n",
" if p_tag.has_attr('style'):\n",
" pass\n",
" else:\n",
" p_tag['style'] = SIG_STYLE\n",
"html_sig = html_sig.prettify(\"utf-8\")\n",
"\n",
"# Finally, assemble the email - text only version is unused at this time.\n",
"text_email = text_body + text_sig \n",
"html_email = html_body + html_sig\n",
"\n",
"# alternately you could just open and read the email html file\n",
"#html_email = open(HTMLfile, 'r').read()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lets see what the email looks like...\n",
"\n",
"**Note:** The image won't show in Notebook, but it will when you send the email!"
]
},
{
"cell_type": "code",
"execution_count": 150,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<html>\n",
" <body>\n",
" <p style=\"font-family:sans-serif;\">\n",
" Dear {{firstName}},\n",
" </p>\n",
" <p style=\"font-family:sans-serif;\">\n",
" Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua\n",
" <a href=\"{{phish}}\">\n",
" Link Test\n",
" </a>\n",
" .\n",
" </p>\n",
" <p style=\"font-family:sans-serif;\">\n",
" Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n",
" </p>\n",
" <p style=\"font-family:sans-serif;\">\n",
" Praesent non turpis lacus. Aenean hendrerit dui justo, a euismod mi luctus ac. Morbi sed tortor vel ante tempor pulvinar. Ut mattis est nisl, ac placerat arcu tincidunt non. Donec condimentum molestie tempus. Suspendisse condimentum feugiat leo dapibus viverra. Sed nec porttitor augue, nec varius augue. Phasellus enim justo, molestie vehicula dictum vel, convallis id diam.\n",
" </p>\n",
" </body>\n",
"</html><html>\n",
" <body>\n",
" <p style=\"font-family:sans-serif;\">\n",
" --\n",
" <br/>\n",
" <strong>\n",
" IT Helpdesk\n",
" </strong>\n",
" <br/>\n",
" <a href=\"mailto:helpdesk@secure-company.com\">\n",
" helpdesk@secure-company.com\n",
" </a>\n",
" </p>\n",
" <p style=\"font-family:sans-serif;\">\n",
" T: (888)PHI-SHME\n",
" <br/>\n",
" A: 123 Derp St., Suite 1000 | Anytown, ON | H0H 0H0\n",
" <br/>\n",
" <a href=\"http://www.company.com\">\n",
" http://www.company.com\n",
" </a>\n",
" <br/>\n",
" <img alt=\"Image Examle\" src=\"cid:image0\"/>\n",
" </p>\n",
" <hr/>\n",
" <table style=\"margin-top: 1em;border-collapse:collapse;\">\n",
" <tbody>\n",
" <tr>\n",
" <td>\n",
" Inline HTML table\n",
" </td>\n",
" <td style=\"padding-left:10px\">\n",
" <p style=\"font-family:sans-serif;\">\n",
" Some stupid disclaimer notice here.\n",
" </p>\n",
" </td>\n",
" </tr>\n",
" </tbody>\n",
" </table>\n",
" </body>\n",
"</html>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(HTML(html_email))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Run all\n",
"\n",
"### At this time it should be safe to run all cells...don't worry anything that sends email requires manual user interaction. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Helper Functions\n",
"\n",
"- **cypher** encodes/decodes addresses into an ID, the cypher part helps disguise the address so someone smart enough to try and decode base64 will get garbage. Set encode to False to decode a string, otherwise just provide a string and this function will encode it. We're not trying to achieve real security with this, just make it a bit tougher to decode for a regular user.\n",
"\n",
"- **phish** assembles and sends the email through SES - you could really easily change the last few lines of this if you don't want to use AWS, there are a million examples on how to send email in Python ... Google is your friend. "
]
},
{
"cell_type": "code",
"execution_count": 162,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def cypher(text, encode=True):\n",
" key = 'qUpUph6vut=e'\n",
" if not encode: text = text.decode('base64')\n",
" cyphered = ''.join(chr(ord(c)^ord(k)) for c,k in izip(text, cycle(key)))\n",
" if encode: cyphered = cyphered.encode('base64', 'strict')\n",
" return cyphered\n",
"\n",
"def phish(to_addr=test_email, first_name=\"Test\", sender=msg_from, url=phish_url, text=text_email, html=html_email):\n",
" global df\n",
" # assemble the phishing link, adding an id parameter for identification of clicks\n",
" uid = cypher(to_addr)\n",
" rl = url + '?id=' + uid\n",
" \n",
" # replace appropriate text, verbose code for clarity.\n",
" text = text.replace('{{firstName}}', first_name).replace('{{phish}}', phish_url)\n",
" html = html.replace('{{firstName}}', first_name).replace('{{phish}}', phish_url)\n",
" \n",
" # Create message container.\n",
" msg = MIMEMultipart('related')\n",
" msg['Subject'] = msg_subject\n",
" msg['From'] = msg_from\n",
" msg['To'] = to_addr\n",
"\n",
" # Attach message parts\n",
" msg.attach(MIMEText(html, \"html\")) \n",
" # Attach image(s)\n",
" for idx, inline_image in enumerate(msg_img): \n",
" msg.attach(inline_image)\n",
"\n",
" # Send the email through AWS SES.\n",
" try:\n",
" pass\n",
" # ************************** uncomment to actually send mail *************************\n",
" #conn.send_raw_email(source=sender, raw_message=msg.as_string(), destinations=to_addr)\n",
" # ************************************************************************************\n",
" except Exception as e:\n",
" success = \"False\"\n",
" print(\"Couldn't send message! Error: %s %s\" % e.message, e.args)\n",
" else:\n",
" success = \"True\"\n",
" finally:\n",
" return success, uid"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test, test, and test again! \n",
"\n",
"Click the button below to send a test email. "
]
},
{
"cell_type": "code",
"execution_count": 152,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [],
"source": [
"def testEmail(btn):\n",
" print('Sending test email...')\n",
" phish(sender=msg_from, first_name=\"Testuser\", to_addr=test_email, url=phish_url, html=html_email)\n",
"\n",
"btn = widgets.Button(description=\"Click here to send a test email...\", icon=\"check\")\n",
"btn.on_click(testEmail)\n",
"display(btn)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Read in the target file (XLS)\n",
"\n",
"We read in a list of targets from an XLS file using Pandas. Then display a little bit of information about the list that we just read..."
]
},
{
"cell_type": "code",
"execution_count": 159,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 email addresses loaded, sample data: \n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>first</th>\n",
" <th>last</th>\n",
" <th>email</th>\n",
" <th>sent</th>\n",
" <th>uid</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>test</td>\n",
" <td>user</td>\n",
" <td>test@email.com</td>\n",
" <td></td>\n",
" <td></td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" first last email sent uid\n",
"0 test user test@email.com "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Some simple logic to make sure the list has been specified\n",
"if email_list:\n",
" df = pd.read_excel(io=email_list, sheetname=0, parse_cols=[0,1,2])\n",
" print(\"%d email addresses loaded, sample data: \" % len(df.index))\n",
" # add some columns for tracking\n",
" df['sent'] = \"\"\n",
" df['uid'] = \"\"\n",
" display(df.head())\n",
" # uncomment the following two lines to see all emails\n",
" #for idx, (last, first, email) in df.iterrows():\n",
" # print first, last, cypher(email)"
]
},
{
"cell_type": "code",
"execution_count": 163,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Casting rod...\n",
"Sending phish to Test User (test@email.com). Sent: BTADITANWxccGBMGHjg=\n"
]
}
],
"source": [
"sent = False\n",
"\n",
"def goPhishing(wut):\n",
" global sent\n",
" if (armed.value and sent is False):\n",
" print \"Casting rod...\"\n",
" sent = True\n",
" for idx, (first, last, email, _, _) in df.iterrows():\n",
" # Remove any spaces and incorrectly formatted data\n",
" first = first.capitalize().strip()\n",
" last = last.capitalize().strip()\n",
" email = email.strip()\n",
" print(\"Sending phish to %s %s (%s).\" %(first, last, email)),\n",
" # I am paranoid so this is TRIPLE saftey.. uncomment the next line to actually send.\n",
" success, uid = phish(sender=msg_from, first_name=first, to_addr=email, url=phish_url, html=html_email)\n",
" if success:\n",
" print(\"Sent: %s\" % uid.rstrip())\n",
" df[\"sent\"][idx] = success\n",
" df[\"uid\"][idx] = uid\n",
" \n",
" elif (armed.value and sent):\n",
" print \"Gear down big rig, emails have already been sent!\"\n",
" else:\n",
" print \"Refusing to send, you must turn of safety first...\"\n",
" \n",
"armed = widgets.ToggleButton(description=\"Click here to turn off safety!\", tooltip=\"Safey switch - emails won't send unless you click this first.\")\n",
"display(armed)\n",
"\n",
"go_button = widgets.Button(description=\"SEND EMAILS\", tooltip=\"WARNING - MAKE SURE YOU REALLY WANT TO DO THIS!\")\n",
"go_button.on_click(goPhishing)\n",
"display(go_button)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Save Excel file with UID and confirmation\n",
"\n",
"TODO: Read in unique hits and password files to add data. "
]
},
{
"cell_type": "code",
"execution_count": 164,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>first</th>\n",
" <th>last</th>\n",
" <th>email</th>\n",
" <th>sent</th>\n",
" <th>uid</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>test</td>\n",
" <td>user</td>\n",
" <td>test@email.com</td>\n",
" <td>True</td>\n",
" <td>BTADITANWxccGBMGHjg=\\n</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" first last email sent uid\n",
"0 test user test@email.com True BTADITANWxccGBMGHjg=\\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Run this cell after emails are sent to see updated datatable...\n",
"if sent:\n",
" display(df.head())\n",
" writer = pd.ExcelWriter(os.path.dirname(email_list) + '\\\\' + \n",
" os.path.basename(email_list).split(\".\")[0] + \n",
" '_done.xlsx', engine='xlsxwriter')\n",
" df.to_excel(writer, sheet_name='Sheet1')\n",
" writer.save()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Decode example\n",
"You can easily decode the ID from your logs if you want to see who is clicking on the link."
]
},
{
"cell_type": "code",
"execution_count": 156,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"BTADITANWxccGBMGHjg=\n",
"\n"
]
}
],
"source": [
"print cypher(\"test@email.com\")"
]
},
{
"cell_type": "code",
"execution_count": 157,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"test@email.com\n"
]
}
],
"source": [
"print cypher(\"BTADITANWxccGBMGHjg=\\n\", False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Notes and Resources\n",
"\n",
"<a id=\"notes\"></a>\n",
"\n",
"1. Example Apache SSL configuration (replace SITENAME with client name and DOMAIN_NAME with FQDN)\n",
"\n",
" ```\n",
" <VirtualHost *:443>\n",
" ServerName www.SITENAME.com\n",
" ServerAlias SITENAME.com\n",
" DocumentRoot /var/www/SITENAME/\n",
"\n",
" CustomLog /var/log/apache2/SITENAME.log combined\n",
" ErrorLog /var/log/apache2/SITENAME.log\n",
"\n",
" SSLEngine on\n",
" # Refer to https://cipherli.st/ for SSL/TLS security best practice. \n",
" SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\n",
" SSLProtocol All -SSLv2 -SSLv3\n",
" SSLHonorCipherOrder On\n",
" # Turn on mod-headers\n",
" Header always set Strict-Transport-Security \"max-age=63072000; includeSubdomains; preload\"\n",
" Header always set X-Frame-Options DENY\n",
" Header always set X-Content-Type-Options nosniff\n",
" # Requires Apache >= 2.4\n",
" #SSLSessionTickets Off\n",
" #SSLCompression off\n",
" #SSLUseStapling on\n",
" #SSLStaplingCache \"shmcb:logs/stapling-cache(150000)\"\n",
"\n",
" SSLCertificateFile \"/etc/letsencrypt/live/DOMAIN_NAME/cert.pem\"\n",
" SSLCertificateKeyFile \"/etc/letsencrypt/live/DOMAIN_NAME/privkey.pem\"\n",
" SSLCertificateChainFile \"/etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem\"\n",
" </VirtualHost>\n",
" ```\n",
"\n",
"2. Let's Encrypt is an easy and free way to get a valid certificate\n",
"\n",
" ```\n",
"sudo -s\n",
"service apache2 stop\n",
"git clone https://github.com/letsencrypt/letsencrypt\n",
"cd letsencrypt\n",
"./letsencrypt-auto certonly --standalone -d example.com -d www.example.com\n",
"service apache2 start\n",
"```\n",
"\n",
"3. Site mirroring \n",
"\n",
" ```\n",
"wget --no-check-certificate -nd -k -p -erobots=off https://SITENAME/\n",
"```\n",
"\n",
"4. Capturing creds with PHP and redirect back to main page with error message (templates):\n",
"\n",
" * [Error page](https://gist.github.com/blark/4c211940be01582a2729)\n",
" * [Capture form data](https://gist.github.com/blark/1ff83db00b7e49cb17ed)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.11"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment