├── .gitignore ├── LICENSE ├── README.md ├── savemail.py ├── sendphish.py └── targets.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | bin/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # Installer logs 26 | pip-log.txt 27 | pip-delete-this-directory.txt 28 | 29 | # Unit test / coverage reports 30 | htmlcov/ 31 | .tox/ 32 | .coverage 33 | .cache 34 | nosetests.xml 35 | coverage.xml 36 | 37 | # Translations 38 | *.mo 39 | 40 | # Mr Developer 41 | .mr.developer.cfg 42 | .project 43 | .pydevproject 44 | 45 | # Rope 46 | .ropeproject 47 | 48 | # Django stuff: 49 | *.log 50 | *.pot 51 | 52 | # Sphinx documentation 53 | docs/_build/ 54 | 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, LCI Technology Group, LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of LCI Technology Group, LLC nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Phishing 2 | ======== 3 | 4 | Scripts used for phishing campaigns 5 | -------------------------------------------------------------------------------- /savemail.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import smtpd 4 | import asyncore 5 | 6 | MAILFILE = 'mailfile.txt' 7 | SERVER = '127.0.0.1' 8 | PORT = 25 9 | 10 | def save_message(fr, to, msg): 11 | with open(MAILFILE, 'a') as mf: 12 | mf.write('FROM: {0}\nTO: {1}\nMSG:\n{2}\n\n'.format(fr, to, msg)) 13 | 14 | 15 | class CustomSMTPServer(smtpd.SMTPServer): 16 | 17 | def process_message(self, peer, mailfrom, rcpttos, data): 18 | print '[*] Saving message for {0}.'.format(rcpttos) 19 | 20 | try: 21 | save_message(mailfrom, rcpttos, data) 22 | except: 23 | pass 24 | 25 | server = CustomSMTPServer((SERVER, PORT), None) 26 | print '[+] Server listening on port {0}'.format(PORT) 27 | asyncore.loop() -------------------------------------------------------------------------------- /sendphish.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | # Send phishing emails by doing the following: 5 | # * Read a JSON file that defines a first name, email address, 6 | # template, and a unique identifier. 7 | # * Create an email message with the data read from the file. 8 | # * Send the email to the specified address. 9 | # 10 | import json 11 | import smtplib 12 | import email.mime.text 13 | import email.utils 14 | 15 | 16 | MX = '' # Hostname for target MX server. 17 | PHISH_MX = '' # Hostname for phishing server. 18 | PHISHFILE = 'targets.json' 19 | CAMP1_ADDR = '' # Source email address for campaign 1. 20 | CAMP2_ADDR = '' # Source email address for campaign 2. 21 | CAMP1_SUBJ = '' # Subject for campaign 1 email. 22 | CAMP2_SUBJ = '' # Subject for campaign 2 email. 23 | CAMP1_URL = 'http:///owa/auth/logon.html?id={0}' 24 | CAMP2_URL = 'http:///awareness.html?id={0}' 25 | 26 | CAMP1_TEMP = ''' 27 |

Hi {0},

28 |

As part of our ongoing effort to protect client data and improve security, 29 | we have recently upgraded the encryption of our email system. To ensure 30 | your email is properly encrypted, please login.

31 |

Thank you for your patience as we work to improve security.

32 |

Regards,

33 |

IT Department

34 | 35 | ''' 36 | 37 | CAMP2_TEMP = ''' 38 |

Hi {0},

39 |

Due to a technical issue in the processing system, there was an error 40 | processing your check. To ensure timely payment, please login 41 | and remedy this error.

42 |

Thank you for your patience as we work to correct this issue.

43 |

Regards,

44 |

HR Department

45 | ''' 46 | 47 | 48 | def send_message(mailfrom, rcptto, data): 49 | try: 50 | server = smtplib.SMTP(MX, 25, PHISH_MX) 51 | server.sendmail(mailfrom, rcptto, data) 52 | 53 | except smtplib.SMTPDataError as e: 54 | print '[-] {0}'.format(str(e[1])) 55 | 56 | except smtplib.SMTPServerDisconnected as e: 57 | print '[-] {0}'.format(str(e)) 58 | 59 | except smtplib.SMTPConnectError as e: 60 | print '[-] {0}'.format(str(e[1])) 61 | 62 | 63 | def read_phish_file(filename): 64 | with open(filename) as pf: 65 | return json.loads(pf.read()) 66 | 67 | 68 | def build_message(template, subj, url, first, vid): 69 | link = url.format(vid) 70 | html = template.format(first, link) 71 | msg = email.mime.text.MIMEText(html, 'html') 72 | msg['Subject'] = subj 73 | msg['Message-ID'] = email.utils.make_msgid() 74 | 75 | return msg 76 | 77 | 78 | if __name__ == '__main__': 79 | phish = read_phish_file(PHISHFILE) 80 | for p in phish['targets']: 81 | if p['campaign'] == 'CAMP1': 82 | msg = build_message(CAMP1_TEMP, CAMP1_SUBJ, CAMP1_URL, p['first'], p['id']) 83 | msg['From'] = CAMP1_ADDR 84 | msg['To'] = p['email'] 85 | print "Sending campaign 1 email to {0} with id {1}".format(p['email'], p['id']) 86 | send_message(CAMP1_ADDR, p['email'], msg.as_string()) 87 | 88 | elif p['campaign'] == 'CAMP2': 89 | msg = build_message(CAMP2_TEMP, CAMP2_SUBJ, CAMP2_URL, p['first'], p['id']) 90 | msg['From'] = CAMP2_ADDR 91 | msg['To'] = p['email'] 92 | print "Sending PR email to {0} with id {1}".format(p['email'], p['id']) 93 | send_message(CAMP2_ADDR, p['email'], msg.as_string()) 94 | 95 | else: 96 | pass 97 | -------------------------------------------------------------------------------- /targets.json: -------------------------------------------------------------------------------- 1 | {"targets": 2 | [ 3 | {"first":"John", "campaign":"CAMP1", "email":"john@target_company.com", "id":"234567"}, 4 | {"first":"Jane", "campaign":"CAMP2", "email":"jane@target_company.com", "id":"765432"} 5 | ] 6 | } 7 | --------------------------------------------------------------------------------