def runDHAThreads(): viewDHAThreadsSummary() print if smtp['addrlist']['r_reject'].keys() or smtp['addrlist']['r_valid'].keys(): fpr('Flushing currently found results (valid/refused recipients) ..') del smtp['dha']['threads']['ok'][:] del smtp['dha']['threads']['fail'][:] smtp['addrlist']['r_reject'].clear() smtp['addrlist']['r_valid'].clear() from pprint import pprint if smtp['dha'].get('cmd') != 'RCPT TO': #chek if sysem support EXPN/VRFY command before threading print if get_yesno_input(' Would you like to test an SMTP server for %s method before threading [y/N]: ' % smtp['dha'].get('cmd')): sc = enumSMTPcmd(v=False,dhost=smtp['connect']['hosts'][0]) # enumSMTPcmd(v=True,dhost=smtp['connect']['hosts'][0]): #pprint(sc) #if smtp['connect']['hosts'][0]['tls_mode'] == 'TLS': #print smtp['dha'].get('cmd') if smtp['dha'].get('cmd') in sc['method']: fpr.ok('Method %s is supported' % smtp['dha'].get('cmd')) else: fpr.fail('Method %s is unsupported' % smtp['dha'].get('cmd')) print fpr('Consider to change an SMTP method!') print t = srThread() t.daemon = True t.delay = smtp['dha']['threads'].get('delay',1) t.threads = smtp['dha']['threads']['reals'].get( 'not',smtp['dha']['threads'].get('not',1) ) t.cpt = smtp['dha']['threads']['reals'].get( 'cpt',smtp['dha']['threads'].get('cpt',get_rcpts('NoR')) ) t.method = smtp['dha'].get('cmd') t.rcpts = smtp['addrlist']['rcpts'] #print get_rcpts('NoR') if get_rcpts('NoR'): if raw_input(' Confirm threading [y/N]:> ') in ['y','Y']: # enable logging from core.msg.sender import Logger logger = Logger() t.run() logger.close() else: print fpr.err('Threading were Cancaled!') else: print fpr.err('Err. No recipients defined!')
def loadSession(): print if not get_yesno_input(' Would you like to load saved session: [y/N]> '): return print fpr('Session files are stored under the session subdirectory by default.\n' \ 'Please provide a full path if you would like to load a session file from different location.') # get the latest file as default: print latest = max(glob.iglob(os.path.join(cfgs['sess_path'], '*.session')), key=os.path.getctime) if latest: fpr('Latest saved session is %s' % os.path.basename(latest)) print sf = raw_input(' [%s]> ' % os.path.basename(latest)) or latest print # if filename does not include path than search file in session dir if not os.path.dirname(sf): sf = cfgs['sess_path'] + '/' + sf if os.path.exists(sf): # import json try: f = open(sf, 'r') # json loads tmp = json.load(f) #from pprint import pprint #pprint(tmp) #TODO: test tmpe dict x = 0 for k in tmp.keys(): if k in [ 'connection', 'signatures', 'replay', 'content', 'headers' ]: x += 1 if x: fpr.ok('Session file seems to be proper') else: fpr.fail('Session file is not proper') return # overwrite main SMTP dict print '=====' #smtp = {k:v for k,v in tmp.items()} for k, v in inSMTPdict(tmp).items(): print k, v smtp[k] = v print '=====' fpr.ok('Session load successful') except IOError as e: fpr.err('Loding session failed: %s' % e) else: fpr.err('Session file does not exist')
def run_wizzard_host(d): # WHAT CAN BE DONE MORE: # - use get)single and get_yesno fun # - modify to support multiple hosts ? fpr('Welcome in Wizzard') print fpr('Please follow .. ') print t = dict() t['host'] = get_single_input('SMTP Host', d.get('host',''),nl='') t['port'] = get_single_input('SMTP Port', d.get('port',''),nl='') t['helo'] = get_single_input('SMTP HELO', d.get('helo',''),nl='') t['smtp_auth_user'] = get_single_input('SMTP AUTH Username ', d.get('smtp_auth_user',''),nl='') t['smtp_auth_pass'] = get_single_input('SMTP AUTH Password ', d.get('smtp_auth_pass',''),nl='') # t['tls_mode'] = get_single_input('SMTP TLS', d.get('tls_mode','NoTLS'),nl='') if d.get('tls_mode') == 'NoTLS': fpr('TLS Mode: Disabled') if get_yesno_input(' > Enable TLS mode [y/N]> '): t['tls_mode'] = 'TLS' fpr('TLS Mode: Enabled') elif d.get('tls_mode') == 'TLS': fpr('TLS Mode: Enabled') if get_yesno_input(' > Disable TLS mode [y/N]> '): t['tls_mode'] = 'NoTLS' fpr('TLS Mode: Disabled') print if raw_input(' Save [Y/n]> ') in ['y', 'Y', '']: print fpr.ok('Settings saved') for k in t.keys(): d[k] = t[k] else: print fpr.fail('Settings not saved!')
def flushDHAThrValues(): if get_yesno_input(' Flush DHA thread settings [y/N]: '): smtp['dha']['cmd'] = 'RCPT TO' smtp['dha']['threads']['not'] = None smtp['dha']['threads']['delay'] = TH_DELAY smtp['dha']['threads']['timeout'] = TH_TIMEOUT smtp['dha']['threads'].pop('cpt', None) smtp['dha']['threads']['reals'].pop('not',None) smtp['dha']['threads']['reals'].pop('cpt',None) fpr.info('DHA threads settings were flushed !')
def flushThrValues(): if get_yesno_input(' Flush thread settings [y/N]: '): smtp['replay']['threads']['delay'] = TH_DELAY smtp['replay']['threads'].pop('rate', None) smtp['replay']['threads'].pop('not', None) smtp['replay']['threads'].pop('rpm', None) smtp['replay']['threads'].pop('mpt', None) smtp['replay']['threads']['reals'].pop('not', None) smtp['replay']['threads']['reals'].pop('rpm', None) smtp['replay']['threads']['reals'].pop('mpt', None) fpr.info('Threads values were flushed !')
def viewEnvelope(): #from core.ui.cless import Less if smtp['addrlist']['rcpts']: if len(smtp['addrlist']['rcpts']) > (tr - 5): if get_yesno_input( ' Would like to use system pager to view it [y/N]:> '): pager = Less(num_lines=tr) print "\n".join(smtp['addrlist']['rcpts']) | pager #print "\n".join(list(' RCPT TO | ' + r for r in smtp['addrlist']['rcpts'])) | pager return print print "\n".join( list(' RCPT TO | ' + r for r in smtp['addrlist']['rcpts']))
def dumpSession(): info('info','Saved session allows to save current connection and message setting to be \n' \ 'useful with further tests, as a proof of successful test or used as template\n\n'\ 'Note: Session file can store sensitive data like SMTP authentication\n' \ ' credential or private keys and certificate.',adj='l') print if not get_yesno_input( ' Would you like to save your current session: [y/N]> '): return print fpr('Session files are stored under the session subdirectory by default.\n' \ 'Please provide a full path if you would like to store you session somehere else.') sessfile = 'minja-' + datetime.now().strftime('%Y%m%d%H%M%S') + '.session' print sf = raw_input(' [%s]> ' % sessfile) or sessfile print if sf == sessfile or not os.path.dirname(sf): sf = cfgs['sess_path'] + '/' + sf if os.path.exists(sf): fpr('Session file already exist') else: if os.access(os.path.dirname(sf), os.W_OK): #the file does not exists but write privileges are given fpr('Saving under %s\n' % sf) #import json dd = outSMTPdict(smtp) try: #f = codecs.open(sf, 'w', encoding='utf-8') f = open(sf, 'w') json.dump(dd, f, indent=3) fpr.ok('Session saving') except IOError as e: fpr.err('Saving file failed: %s' % e) else: fpr.fail('Missing write permission')
def mail_body_parser(body): if not hasattr(body, 'as_string'): fpr.err('Message can not be processed or not loaded !') return b = email.message_from_string(body.as_string()) btype = b.get_content_type() dbginfo('debug', 'btype is %s' % btype) print # parse the body and save split parts in dictionary dparts = dict() body_parser(dparts, b) fpr.cyan('=' * (tc - 4)) # pprint(dparts) if DEBUG: dbginfo('debug', str(dparts.keys())) fpr.cyan('=' * (tc - 4)) ## build a dictionary print if not dparts.keys(): fpr('No MIME parts found') return mimemulti = ['multipart/mixed', 'multipart/alternative'] print mimemulti while True: bancls() fpr('Message MIME structure') print fpr('_' * (tc - 4)) print bstrio = StringIO() _structure(b, bstrio) fpr.warn('%s' % bstrio.getvalue()) #fpr.warn(_structure(bpart)) fpr('_' * (tc - 4)) print fpr('MIME parts ready to review:') print for k in dparts.keys(): #print k #print type(k) if dparts[k]['type'] in mimemulti: fpr.info(' [%s] %s ' % (k, dparts[k]['type'][:69])) else: fpr(' [%s] %s ' % (k, dparts[k]['type'][:69])) print op = raw_input(' []> ') # dparts keys are int not strings if op.isdigit(): k = int(op) if op == '': break while k in dparts.keys(): bancls() fpr('MIME Headers: %s' % k) fpr('_' * (tc - 4)) print for (h, hv) in dparts[k]['mheaders']: fpr('%s: %s' % (h, hv)) fpr('_' * (tc - 4)) print # pprint(dparts) # waitin() if dparts[k].get('type') in mimemulti: fpr.warn('This part is not directly viewable') waitin() break elif dparts[k].get('payload'): fpr('Choose option:') print fpr(' 1) view payload') fpr(' 2) save payload') fpr.off(' 3) attach payload to composer [?future feature?]') print op = raw_input(' []> ') if op == '': waitin() break # --- view payload --- if op in ['1']: bancls() fpr('MIME Payload ') print fpr.warn('%s' % dparts[k].get('type')) print xe = 0 for (h, hv) in dparts[k].get('mheaders'): #fpr('%s: %s' % (h,hv)) if h.lower() == 'content-transfer-encoding': #part['encext'] = '.'+hv.lower() if hv in ['base64']: info( 'info', 'This payload is base64 encoded. You can view it as it is or try to decode it first.' ) print if get_yesno_input( ' Would like to decode the payload first [y/N]:> ' ): dp = decode_attch(dparts[k]['payload']) #pprint(dp) #print len(dp.get('raw')) #print len(str(dp)) if len(dp.get('raw')) > tr: #if True: if get_yesno_input( ' Would like to use system pager to view it [y/N]:> ' ): fpr('_' * (tc - 4)) print pager = Less(num_lines=tr) print dp.get('raw') | pager fpr('_' * (tc - 4)) else: fpr('_' * (tc - 4)) print fpr(dp.get('raw')) print fpr('_' * (tc - 4)) waitin() xe = 1 break # if viewed decoded part do not display encoded one if xe: break print if len(dparts[k].get('payload')) > tr: if get_yesno_input( ' Would like to use system pager to view it [y/N]:> ' ): fpr('_' * (tc - 4)) print pager = Less(num_lines=tr) print dparts[k]['payload'] | pager fpr('_' * (tc - 4)) else: fpr('_' * (tc - 4)) print fpr(dparts[k]['payload']) print fpr('_' * (tc - 4)) else: fpr('_' * (tc - 4)) print if type(dparts[k].get('payload')) is not 'str': fpr.err('An error occured') else: fpr(dparts[k].get('payload')) print fpr('_' * (tc - 4)) waitin() if op in ['2']: bancls() fpr('MIME Payload export') fpr('Choose option:') print fpr(' 1) save payload, as it is (no decoding)') fpr(' 2) save payload - base64 decoded') print op = raw_input(' []> ') print if op == '': waitin() break if op in ['1']: bancls() mpart_saver(dparts[k], 1) waitin() if op in ['2']: bancls() mpart_saver(dparts[k], 2) waitin() break else: fpr.warn( 'Wrr: Empty payloyd. Message malformed or parsing has failed.' ) waitin() break
def mpart_saver(part, op): if op == 1: #save as it is, no decoding #pprint(part) part['encext'] = None for (h, hv) in part['mheaders']: #fpr('%s: %s' % (h,hv)) if h.lower() == 'content-transfer-encoding': part['encext'] = '.' + hv.lower() print if not get_yesno_input(' Would you like to save this part: [y/N]> '): return print if part['filename']: fn = part['filename'] + part['encext'] else: fn = 'minja-' + part['type'].replace( '/', '_') + '-' + datetime.now().strftime( '%Y%m%d%H%M%S') + part['encext'] print fn = raw_input(' [%s]> ' % fn) or fn print #if sf == sessfile or not os.path.dirname(sf): # sf = cfgs['sess_path']+'/'+sf if not os.path.dirname(fn): fn = cfgs['mparts_path'] + '/' + fn if os.path.exists(fn): fpr('File already exist') else: if os.access(os.path.dirname(fn), os.W_OK): #the file does not exists but write privileges are given fpr('Saving under %s\n' % fn) try: #f = codecs.open(fn, 'w', encoding='utf-8') f = open(fn, 'w') f.write(part['payload']) f.close() fpr.ok('Session saving') except IOError as e: fpr.err('Saving file failed: %s' % e) else: fpr.fail('Missing write permission') if op == 2: #decode base64 first print if not get_yesno_input(' Would you like to save this part: [y/N]> '): return print if part['filename']: fn = part['filename'] else: fn = 'minja-' + part['type'].replace( '/', '_') + '-' + datetime.now().strftime('%Y%m%d%H%M%S') print fn = raw_input(' [%s]> ' % fn) or fn print #if sf == sessfile or not os.path.dirname(sf): # sf = cfgs['sess_path']+'/'+sf if not os.path.dirname(fn): fn = cfgs['mparts_path'] + '/' + fn if os.path.exists(fn): fpr('File already exist') else: if os.access(os.path.dirname(fn), os.W_OK): #the file does not exists but write privileges are given fpr('Saving under %s\n' % fn) try: #f = codecs.open(fn, 'w', encoding='utf-8') f = open(fn, 'wb') d = decode_attch(part['payload']) #pprint(d) f.write(d['raw']) f.close() fpr.ok('Session saving') except IOError as e: fpr.err('Saving file failed: %s' % e) else: fpr.fail('Missing write permission')
print fpr.warn('Verification skipped. No identity found') waitin() return if not dd.get('ip'): print fpr.warn('Verification skipped. Missing client IP address!') waitin() return # if SPF Policy is defined manually skip DNS and use it if dd.get('policy'): #fpr('SPF record supplied by input is found! ') fpr('Policy origin: User input\n\n') if get_yesno_input( ' Run validation against supplied SPF record [y/N]: > '): print fpr('Policy origin: INPUT\n\n') fpr('_' * (tc - 4)) print fpr.green('%s' % dd['policy']) fpr('_' * (tc - 4)) print fpr('Evaluating policy mechanism ..') print spfmech(dd['policy'], q, 1) print return if True: print fpr('Policy origin: DNS/TXT RR\n\n')