def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' feathermodules.analysis_results = ca.analyze_ciphertext( feathermodules.samples, verbose=True) if feathermodules.analysis_results[ 'decoded_ciphertexts'] != feathermodules.samples: feathermodules.samples = feathermodules.analysis_results[ 'decoded_ciphertexts'] for attack in feathermodules.module_list.keys(): if len( set(feathermodules.module_list[attack]['keywords']) & set(feathermodules.analysis_results['keywords'])) > 0: print 'Running module: %s' % attack feathermodules.current_options = feathermodules.module_list[ attack]['options'] if debug: print feathermodules.module_list[attack][ 'attack_function'](feathermodules.samples) else: try: print feathermodules.module_list[attack][ 'attack_function'](feathermodules.samples) except: print '[*] Module execution failed, please report this issue at https://github.com/nccgroup/featherduster/issues'
def get_arguments(ciphertexts): arguments = {} arguments['ciphertexts'] = ciphertexts analysis_results = ca.analyze_ciphertext(ciphertexts) blocksize = analysis_results['blocksize'] while True: print '[+] Block size detected as %d' % blocksize blocksize_answer = raw_input('Is this correct (yes)? ') if blocksize_answer.lower() in ['', 'yes', 'y']: arguments['blocksize'] = blocksize break else: blocksize_answer = raw_input( 'Please enter the correct blocksize: ') try: arguments['blocksize'] = int(blocksize_answer) break except: print '[*] Answer could not be interpreted as a number. Defaulting to detected block size.' arguments['blocksize'] = blocksize continue hollywood_answer = raw_input( 'Do you want hacker movie style output at a minor cost to performance (no I am lame)? ' ) arguments['hollywood'] = (hollywood_answer.lower() in ['', 'n', 'no', 'no i am lame']) return arguments
def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True, do_more_checks=True) if analysis_results['decoded_ciphertexts'] != feathermodules.samples: feathermodules.samples = analysis_results['decoded_ciphertexts'] for attack in feathermodules.module_list.keys(): if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0: print feathermodules.module_list[attack]['attack_function'](feathermodules.samples)
def prepare_options(options, ciphertexts): if options['method'].lower() == 'post': options['method'] = 'post' elif options['method'].lower() == 'get': options['method'] = 'get' else: print '[*] Only POST and GET are currently supported by this module.' return False if options['encoding'] not in ['hex', 'base64']: print '[*] Only hex and base64 encoding are currently supported by this module.' if '*' in options['url']: options['url'] = string.replace(options['url'], "'", "\\'") options['url'] = string.replace(options['url'], '*', "'+ciphertext+'") if options['post_body'] != '': options['post_body'] = string.replace(options['post_body'], '*', "'+ciphertext+'") options['post_body'] = ",data='" + options['post_body'] + "'" if options['blocksize'] == 'auto': analysis_results = ca.analyze_ciphertext(ciphertexts) if analysis_results['blocksize'] == 0: print '[*] Couldn\'t detect a common blocksize.' return False options['blocksize'] = analysis_results['blocksize'] else: try: options['blocksize'] = int(options['blocksize']) except: print '[*] Blocksize could not be interpreted as a number.' return False # We don't currently support any padding type but pkcs7 options['padding_type'] = 'pkcs7' if options['iv'] == '': print '[+] No IV provided, defaulting to null block.' options['iv'] = '00' * options['blocksize'] else: try: options['iv'].decode('hex') except: print '[*] IV was not in the correct format. Please provide a hex-encoded IV with length matching the blocksize.' return False if (len(options['iv']) / 2) != options['blocksize']: print '[*] IV was not the correct length. Please provide a hex-encoded IV with length matching the blocksize.' return False options['hollywood'] = (options['hollywood'].lower() not in ['', 'n', 'no', 'no i am lame']) return options
def prepare_options(options, ciphertexts): if options['blocksize'] == 'auto': analysis_results = ca.analyze_ciphertext(ciphertexts) if analysis_results['blocksize'] == 0: print '[*] Couldn\'t detect a common blocksize.' return False options['blocksize'] = analysis_results['blocksize'] else: try: options['blocksize'] = int(options['blocksize']) except: print '[*] Blocksize could not be interpreted as a number.' return False # If we actually supported anything but pkcs7, here we would do: # arguments['padding_type'] = raw_input(padding_menu) # But we don't, so we: options['padding_type'] = 'pkcs7' if options['iv'] == '': print '[+] No IV provided, defaulting to null block.' options['iv'] = '00' * options['blocksize'] else: try: options['iv'].decode('hex') except: print '[*] IV was not in the correct format. Please provide a hex-encoded IV with length matching the blocksize.' return False if (len(options['iv']) / 2) != options['blocksize']: print '[*] IV was not the correct length. Please provide a hex-encoded IV with length matching the blocksize.' return False # We don't use this yet, commented out for now. ''' while True: prefix_answer = raw_input('Do you need to use a prefix (no)? ') if prefix_answer.lower() not in ['','n','no']: prefix = raw_input('Please enter the prefix you want to use, hex encoded: ') try: arguments['prefix'] = prefix.decode('hex') break except: print '[*] Couldn\'t decode your entry. Is it properly hex encoded?' continue else: arguments['prefix'] = '' break ''' options['hollywood'] = (options['hollywood'].lower() not in ['', 'n', 'no', 'no i am lame']) return options
def prepare_options(options, ciphertexts): if options['blocksize'] == 'auto': analysis_results = ca.analyze_ciphertext(ciphertexts) if analysis_results['blocksize'] == 0: print '[*] Couldn\'t detect a common blocksize.' return False options['blocksize'] = analysis_results['blocksize'] else: try: options['blocksize'] = int(options['blocksize']) except: print '[*] Blocksize could not be interpreted as a number.' return False # If we actually supported anything but pkcs7, here we would do: # arguments['padding_type'] = raw_input(padding_menu) # But we don't, so we: options['padding_type'] = 'pkcs7' if options['iv'] == '': print '[+] No IV provided, defaulting to null block.' options['iv'] = '00'*options['blocksize'] else: try: options['iv'].decode('hex') except: print '[*] IV was not in the correct format. Please provide a hex-encoded IV with length matching the blocksize.' return False if (len(options['iv'])/2) != options['blocksize']: print '[*] IV was not the correct length. Please provide a hex-encoded IV with length matching the blocksize.' return False # We don't use this yet, commented out for now. ''' while True: prefix_answer = raw_input('Do you need to use a prefix (no)? ') if prefix_answer.lower() not in ['','n','no']: prefix = raw_input('Please enter the prefix you want to use, hex encoded: ') try: arguments['prefix'] = prefix.decode('hex') break except: print '[*] Couldn\'t decode your entry. Is it properly hex encoded?' continue else: arguments['prefix'] = '' break ''' options['hollywood'] = (options['hollywood'].lower() not in ['','n','no','no i am lame']) return options
def prepare_options(options, ciphertexts): if options['method'].lower() == 'post': options['method'] = 'post' elif options['method'].lower() == 'get': options['method'] = 'get' else: print '[*] Only POST and GET are currently supported by this module.' return False if options['encoding'] not in ['hex','base64']: print '[*] Only hex and base64 encoding are currently supported by this module.' if '*' in options['url']: options['url'] = string.replace(options['url'],"'","\\'") options['url'] = string.replace(options['url'],'*',"'+ciphertext+'") if options['post_body'] != '': options['post_body'] = string.replace(options['post_body'],'*',"'+ciphertext+'") options['post_body'] = ",data='" + options['post_body'] + "'" if options['blocksize'] == 'auto': analysis_results = ca.analyze_ciphertext(ciphertexts) if analysis_results['blocksize'] == 0: print '[*] Couldn\'t detect a common blocksize.' return False options['blocksize'] = analysis_results['blocksize'] else: try: options['blocksize'] = int(options['blocksize']) except: print '[*] Blocksize could not be interpreted as a number.' return False # We don't currently support any padding type but pkcs7 options['padding_type'] = 'pkcs7' if options['iv'] == '': print '[+] No IV provided, defaulting to null block.' options['iv'] = '00'*options['blocksize'] else: try: options['iv'].decode('hex') except: print '[*] IV was not in the correct format. Please provide a hex-encoded IV with length matching the blocksize.' return False if (len(options['iv'])/2) != options['blocksize']: print '[*] IV was not the correct length. Please provide a hex-encoded IV with length matching the blocksize.' return False options['hollywood'] = (options['hollywood'].lower() not in ['','n','no','no i am lame']) return options
def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True) if analysis_results['decoded_ciphertexts'] != feathermodules.samples: feathermodules.samples = analysis_results['decoded_ciphertexts'] print '' print '[+] Suggested modules:' for attack in feathermodules.module_list.keys(): if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0: print ' {0:<20} - {1:<57}'.format(attack, feathermodules.module_list[attack]['description'])
def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True) if analysis_results['decoded_ciphertexts'] != feathermodules.samples: feathermodules.samples = analysis_results['decoded_ciphertexts'] for attack in feathermodules.module_list.keys(): if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0: print 'Running module: %s' % attack feathermodules.current_options = feathermodules.module_list[attack]['options'] print feathermodules.module_list[attack]['attack_function'](feathermodules.samples)
def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' feathermodules.analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True) if feathermodules.analysis_results['decoded_ciphertexts'] != feathermodules.samples: decode = raw_input('[+] Analysis suggests encoded samples. Decode before continuing (Y/n)? ') if decode.lower() not in ('n','no','nope','nah','no thank you'): feathermodules.samples = feathermodules.analysis_results['decoded_ciphertexts'] print '' print '[+] Suggested modules:' for attack in feathermodules.module_list.keys(): if len(set(feathermodules.module_list[attack]['keywords']) & set(feathermodules.analysis_results['keywords'])) > 0: print ' {0:<20} - {1:<57}'.format(attack, feathermodules.module_list[attack]['description'])
def process_options(options, ciphertexts): if options['blocksize'] == 'auto': print '[+] Analyzing samples to discover block size...' analysis_results = ca.analyze_ciphertext(ciphertexts) blocksize = analysis_results['blocksize'] if blocksize == 0: print '[*] No common block size could be discovered.' else: options['blocksize'] = blocksize else: try: print '[+] Checking block size...' options['blocksize'] = int(options['blocksize']) except: return False options['hollywood'] = (options['hollywood'].lower() not in ['','n','no','no i am lame']) return options
def process_options(options, ciphertexts): if options['blocksize'] == 'auto': print '[+] Analyzing samples to discover block size...' analysis_results = ca.analyze_ciphertext(ciphertexts) blocksize = analysis_results['blocksize'] if blocksize == 0: print '[*] No common block size could be discovered.' else: options['blocksize'] = blocksize else: try: print '[+] Checking block size...' options['blocksize'] = int(options['blocksize']) except: return False options['hollywood'] = (options['hollywood'].lower() not in ['', 'n', 'no', 'no i am lame']) return options
def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' feathermodules.analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True) if feathermodules.analysis_results['decoded_ciphertexts'] != feathermodules.samples: feathermodules.samples = feathermodules.analysis_results['decoded_ciphertexts'] for attack in feathermodules.module_list.keys(): if len(set(feathermodules.module_list[attack]['keywords']) & set(feathermodules.analysis_results['keywords'])) > 0: print 'Running module: %s' % attack feathermodules.current_options = feathermodules.module_list[attack]['options'] if debug: print feathermodules.module_list[attack]['attack_function'](feathermodules.samples) else: try: print feathermodules.module_list[attack]['attack_function'](feathermodules.samples) except: print '[*] Module execution failed, please report this issue at https://github.com/nccgroup/featherduster/issues'
def run(self, line): if len(feathermodules.samples) == 0: print 'No loaded samples. Please use the \'import\' command.' return False print '[+] Analyzing samples...' analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True) if analysis_results['decoded_ciphertexts'] != feathermodules.samples: decode = raw_input( '[+] Analysis suggests encoded samples. Decode before continuing (Y/n)? ' ) if decode.lower() not in ('n', 'no', 'nope', 'nah', 'no thank you'): feathermodules.samples = analysis_results[ 'decoded_ciphertexts'] print '' print '[+] Suggested modules:' for attack in feathermodules.module_list.keys(): if len( set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0: print ' {0:<20} - {1:<57}'.format( attack, feathermodules.module_list[attack]['description'])
def get_arguments(ciphertexts): arguments = {} arguments['ciphertexts'] = ciphertexts analysis_results = ca.analyze_ciphertext(ciphertexts) blocksize = analysis_results['blocksize'] while True: print '[+] Block size detected as %d' % blocksize blocksize_answer = raw_input('Is this correct (yes)? ') if blocksize_answer.lower() in ['', 'yes', 'y']: arguments['blocksize'] = blocksize break else: blocksize_answer = raw_input('Please enter the correct blocksize: ') try: arguments['blocksize'] = int(blocksize_answer) break except: print '[*] Answer could not be interpreted as a number. Defaulting to detected block size.' arguments['blocksize'] = blocksize continue # If we actually supported anything but pkcs7, here we would do: # arguments['padding_type'] = raw_input(padding_menu) # But we don't, so we: arguments['padding_type'] = 'pkcs7' while True: iv_answer = raw_input('Do you want to specify an IV (no)? ') if iv_answer.lower() not in ['','n','no']: iv_hex = raw_input('What is the IV (hex encoded)?') try: iv_raw = iv_hex.decode('hex') if len(iv_raw) != arguments['blocksize']: arguments['iv'] = iv_raw break else: print '[*] Your IV does not match the blocksize of %d.' % arguments['blocksize'] continue except: arguments['iv'] = None print '[*] You entered something that wasn\'t proper hex and wasn\'t \'no\'.' continue else: print '[+] Defaulting to all-null IV. If the IV is not a null block, expect the first block of output to be garbled.' arguments['iv'] = None break while True: prefix_answer = raw_input('Do you need to use a prefix (no)? ') if prefix_answer.lower() not in ['','n','no']: prefix = raw_input('Please enter the prefix you want to use, hex encoded: ') try: arguments['prefix'] = prefix.decode('hex') break except: print '[*] Couldn\'t decode your entry. Is it properly hex encoded?' continue else: arguments['prefix'] = '' break hollywood_answer = raw_input('Do you want hacker movie style output at a minor cost to performance (no I am lame)? ') arguments['hollywood'] = (hollywood_answer.lower() not in ['','n','no','no i am lame']) return arguments
cbc_cipher = AES.new(key, AES.MODE_CBC, iv) cbc_ciphertexts = [cbc_cipher.encrypt(ca.pkcs7_pad(plaintext,AES.block_size))] cbc_cipher = AES.new(key, AES.MODE_CBC, iv) cbc_ciphertexts.append(cbc_cipher.encrypt(ca.pkcs7_pad(plaintext2,AES.block_size))) mb_xor_ciphertexts = [ca.sxor(plaintext,"\xfa\x4e\x77\x01\x43"*len(plaintext))] mb_xor_ciphertexts.append(ca.sxor(plaintext2,"\xfa\x4e\x77\x01\x43"*len(plaintext2))) two_time_pad_ciphertexts = [ca.sxor(plaintext,two_time_pad_key)] two_time_pad_ciphertexts.append(ca.sxor(plaintext2,two_time_pad_key)) compressed_messages = [compress(plaintext), compress(plaintext2)] print 'Analyzing ECB ciphertexts...' ecb_results = ca.analyze_ciphertext(ecb_ciphertexts) if 'ecb' not in ecb_results['keywords']: exit('ECB detection is broken.') print 'Analyzing CBC fixed-IV ciphertexts...' cbc_results = ca.analyze_ciphertext(cbc_ciphertexts) if 'cbc_fixed_iv' not in cbc_results['keywords']: exit('CBC fixed IV detection is broken.') print 'Analyzing multi-byte XOR ciphertexts...' multi_byte_xor_results = ca.analyze_ciphertext(mb_xor_ciphertexts) if 'individually_low_entropy' not in multi_byte_xor_results['keywords']: exit('Multi-byte XOR not flagged as weak crypto.') print 'Analyzing two-time pad ciphertexts...' two_time_pad_results = ca.analyze_ciphertext(two_time_pad_ciphertexts)
sample_file = filename sample_fh = open(sample_file,'r') samples.append(sample_fh.read()) sys.argv = [] else: samples.extend(import_samples()) if raw_input('Would you like to enter additional samples (y/N)?').lower() not in ['y','yes']: no_more = True # Build module list attack_selection_method = get_attack_selection_method() if attack_selection_method == 'b': continue elif attack_selection_method in ['a', 'p']: print '[+] Analyzing samples...' analysis_results = ca.analyze_ciphertext(samples, verbose=True, do_more_checks=True) print '' if analysis_results['decoded_ciphertexts'] != samples: samples = analysis_results['decoded_ciphertexts'] if raw_input('The imported samples were encoded. Do you want to show the decoded samples (no)? ').lower() in ['y','yes']: print 'Samples:\n' + '-'*40 for sample in samples: print repr(sample) print '-'*40 + '\n' elif attack_selection_method == 's': search_term = raw_input("Please enter your search term: ") # Present attack options selected_attack = '' while selected_attack.lower() not in ['back', 'b']:
print "\n".join([ct.encode('hex') for ct in cbc_ciphertexts]) mb_xor_ciphertexts = [ca.sxor(plaintext,"\xfa\x4e\x77\x01\x43"*len(plaintext))] mb_xor_ciphertexts.append(ca.sxor(plaintext2,"\xfa\x4e\x77\x01\x43"*len(plaintext2))) print 'Multi-byte XOR ciphertexts are:' print "\n".join([ct.encode('hex') for ct in mb_xor_ciphertexts]) two_time_pad_ciphertexts = [ca.sxor(plaintext,two_time_pad_key)] two_time_pad_ciphertexts.append(ca.sxor(plaintext2,two_time_pad_key)) print 'Two-time pad ciphertexts are:' print "\n".join([ct.encode('hex') for ct in two_time_pad_ciphertexts]) compressed_messages = [compress(plaintext), compress(plaintext2)] print 'Analyzing ECB ciphertexts...' ca.analyze_ciphertext(ecb_ciphertexts,verbose=True) print '' print 'Analyzing CBC fixed-IV ciphertexts...' ca.analyze_ciphertext(cbc_ciphertexts,verbose=True) print '' print 'Analyzing multi-byte XOR ciphertexts...' ca.analyze_ciphertext(mb_xor_ciphertexts,verbose=True) print '' print 'Analyzing two-time pad ciphertexts...' ca.analyze_ciphertext(two_time_pad_ciphertexts,verbose=True) print '' print 'Analyzing hex-encoded ciphertext...' ca.analyze_ciphertext([ct.encode('hex') for ct in ecb_ciphertexts],verbose=True) print '' print 'Analyzing base64-encoded ciphertext...' ca.analyze_ciphertext([ct.encode('base64') for ct in ecb_ciphertexts],verbose=True)
def get_arguments(ciphertexts): arguments = {} arguments['ciphertexts'] = ciphertexts analysis_results = ca.analyze_ciphertext(ciphertexts) blocksize = analysis_results['blocksize'] while True: print '[+] Block size detected as %d' % blocksize blocksize_answer = raw_input('Is this correct (yes)? ') if blocksize_answer.lower() in ['', 'yes', 'y']: arguments['blocksize'] = blocksize break else: blocksize_answer = raw_input( 'Please enter the correct blocksize: ') try: arguments['blocksize'] = int(blocksize_answer) break except: print '[*] Answer could not be interpreted as a number. Defaulting to detected block size.' arguments['blocksize'] = blocksize continue # If we actually supported anything but pkcs7, here we would do: # arguments['padding_type'] = raw_input(padding_menu) # But we don't, so we: arguments['padding_type'] = 'pkcs7' while True: iv_answer = raw_input('Do you want to specify an IV (no)? ') if iv_answer.lower() not in ['', 'n', 'no']: iv_hex = raw_input('What is the IV (hex encoded)? ') try: iv_raw = iv_hex.decode('hex') if len(iv_raw) == arguments['blocksize']: arguments['iv'] = iv_raw break else: print '[*] Your IV does not match the blocksize of %d.' % arguments[ 'blocksize'] continue except: arguments['iv'] = None print '[*] You entered something that wasn\'t proper hex and wasn\'t \'no\'.' continue else: print '[+] Defaulting to all-null IV. If the IV is not a null block, expect the first block of output to be garbled.' arguments['iv'] = None break # We don't use this yet, commented out for now. ''' while True: prefix_answer = raw_input('Do you need to use a prefix (no)? ') if prefix_answer.lower() not in ['','n','no']: prefix = raw_input('Please enter the prefix you want to use, hex encoded: ') try: arguments['prefix'] = prefix.decode('hex') break except: print '[*] Couldn\'t decode your entry. Is it properly hex encoded?' continue else: arguments['prefix'] = '' break ''' hollywood_answer = raw_input( 'Do you want hacker movie style output at a minor cost to performance (no I am lame)? ' ) arguments['hollywood'] = (hollywood_answer.lower() not in ['', 'n', 'no', 'no i am lame']) return arguments
samples.append(sample_fh.read()) sys.argv = [] else: samples.extend(import_samples()) if raw_input('Would you like to enter additional samples (y/N)?' ).lower() not in ['y', 'yes']: no_more = True # Build module list attack_selection_method = get_attack_selection_method() if attack_selection_method == 'b': continue elif attack_selection_method in ['a', 'p']: print '[+] Analyzing samples...' analysis_results = ca.analyze_ciphertext(samples, verbose=True, do_more_checks=True) print '' if analysis_results['decoded_ciphertexts'] != samples: samples = analysis_results['decoded_ciphertexts'] if raw_input( 'The imported samples were encoded. Do you want to show the decoded samples (no)? ' ).lower() in ['y', 'yes']: print 'Samples:\n' + '-' * 40 for sample in samples: print repr(sample) print '-' * 40 + '\n' elif attack_selection_method == 's': search_term = raw_input("Please enter your search term: ") # Present attack options
ca.sxor(plaintext, "\xfa\x4e\x77\x01\x43" * len(plaintext)) ] mb_xor_ciphertexts.append( ca.sxor(plaintext2, "\xfa\x4e\x77\x01\x43" * len(plaintext2))) print 'Multi-byte XOR ciphertexts are:' print "\n".join([ct.encode('hex') for ct in mb_xor_ciphertexts]) two_time_pad_ciphertexts = [ca.sxor(plaintext, two_time_pad_key)] two_time_pad_ciphertexts.append(ca.sxor(plaintext2, two_time_pad_key)) print 'Two-time pad ciphertexts are:' print "\n".join([ct.encode('hex') for ct in two_time_pad_ciphertexts]) compressed_messages = [compress(plaintext), compress(plaintext2)] print 'Analyzing ECB ciphertexts...' ca.analyze_ciphertext(ecb_ciphertexts, verbose=True) print '' print 'Analyzing CBC fixed-IV ciphertexts...' ca.analyze_ciphertext(cbc_ciphertexts, verbose=True) print '' print 'Analyzing multi-byte XOR ciphertexts...' ca.analyze_ciphertext(mb_xor_ciphertexts, verbose=True) print '' print 'Analyzing two-time pad ciphertexts...' ca.analyze_ciphertext(two_time_pad_ciphertexts, verbose=True) print '' print 'Analyzing hex-encoded ciphertext...' ca.analyze_ciphertext([ct.encode('hex') for ct in ecb_ciphertexts], verbose=True) print '' print 'Analyzing base64-encoded ciphertext...'
cbc_ciphertexts.append( cbc_cipher.encrypt(ca.pkcs7_pad(plaintext2, AES.block_size))) mb_xor_ciphertexts = [ ca.sxor(plaintext, "\xfa\x4e\x77\x01\x43" * len(plaintext)) ] mb_xor_ciphertexts.append( ca.sxor(plaintext2, "\xfa\x4e\x77\x01\x43" * len(plaintext2))) two_time_pad_ciphertexts = [ca.sxor(plaintext, two_time_pad_key)] two_time_pad_ciphertexts.append(ca.sxor(plaintext2, two_time_pad_key)) compressed_messages = [compress(plaintext), compress(plaintext2)] print 'Analyzing ECB ciphertexts...' ecb_results = ca.analyze_ciphertext(ecb_ciphertexts) if 'ecb' not in ecb_results['keywords']: exit('ECB detection is broken.') print 'Analyzing CBC fixed-IV ciphertexts...' cbc_results = ca.analyze_ciphertext(cbc_ciphertexts) if 'cbc_fixed_iv' not in cbc_results['keywords']: exit('CBC fixed IV detection is broken.') print 'Analyzing multi-byte XOR ciphertexts...' multi_byte_xor_results = ca.analyze_ciphertext(mb_xor_ciphertexts) if 'individually_low_entropy' not in multi_byte_xor_results['keywords']: exit('Multi-byte XOR not flagged as weak crypto.') print 'Analyzing two-time pad ciphertexts...' two_time_pad_results = ca.analyze_ciphertext(two_time_pad_ciphertexts)