source: trunk/bin/bletchley-analyze @ 59

Last change on this file since 59 was 46, checked in by tmorgan, 11 years ago

fixed highlighting bug

  • Property svn:executable set to *
File size: 5.1 KB
RevLine 
[40]1#!/usr/bin/env python3
[1]2
[40]3# Requires Python 3+
[1]4
5'''
6Simple script to leverage some of the blobtools features
7
8Copyright (C) 2011-2012 Virtual Security Research, LLC
9Author: Timothy D. Morgan
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU Lesser General Public License, version 3,
13 as published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program.  If not, see <http://www.gnu.org/licenses/>.
22'''
23
24
25import sys
26import argparse
27import binascii
28from bletchley import blobtools,buffertools
29
30
[28]31parser = argparse.ArgumentParser(
32    description='Analyzes samples of encrypted data in an attempt to decode'
33    ' samples to binary and identify patterns useful in cryptanalysis.'
34    ' For more information, see:  http://code.google.com/p/bletchley/wiki/Overview')
[1]35parser.add_argument('input_file', nargs='?', default=None,
[28]36                    help='File containing encrypted blobs to analyze, one per'
37                    ' line. Omit to read from stdin.')
[13]38parser.add_argument('-e', dest='encoding_chain', type=str, default=None,
[28]39                    help='Comma-separated sequence of formats used to encode'
40                    ' the tokens, beginning with the last one applied. '
41                    '(default: auto-detect. Use "?" for a listing of supported encodings.)')
[13]42parser.add_argument('-b', dest='block_size', type=int, default=8,
43                    help='The block size displayed and used in highlighting (default: 8)')
[1]44parser.add_argument('-p', dest='output_lines', type=int, default=10,
45                    help='Number of lines of input to display in decoded form.')
46parser.add_argument('-c', action='store_const', const=True, default=False,
47                    help='Use color output for decoded highlights.')
48parser.add_argument('-c256', action='store_const', const=True, default=False,
49                    help='Use 256 color output for decoded highlights.')
50options = parser.parse_args()
51
[28]52if options.encoding_chain == '?':
53    print('\n\t'.join(['Supported encodings:']+blobtools.supportedEncodings()))
54    sys.exit(0)
55
[40]56input_file = sys.stdin.buffer
[1]57if options.input_file is not None:
[40]58    input_file = open(options.input_file, 'rb')
[1]59
[40]60blobs = input_file.read().rstrip(b'\n').replace(b'\r', b'').split(b'\n')
[1]61#print(repr(blobs))
62
63def terminalHighlightedString(code, s):
64    global options
65    if code == None:
66        return s
67
68    if options.c256:
69        fg = code%216+16
70        bg = (code^0xffffffff)%216+16
71        return "\x1b[0;38;05;%d;48;05;%dm%s\x1b[0m" % (fg,bg,s)
72    elif options.c:
73        fg = code%6+31
74        bg = (code^0xffffffff)%6+41
75        return "\x1b[0;%d;%dm%s\x1b[0m" % (fg,bg,s)
76    else:
77        return "\x1b[7m%s\x1b[0m" % s
78
79
80def printColoredHexDump(blobs, group_size=8):   
[9]81    line_size = 64
[1]82    group_size *= 2 # two hex digits per byte
[40]83    hex_blobs = [binascii.b2a_hex(b) for b in blobs]
[1]84    color_map = buffertools.blockWiseColorMap(group_size, hex_blobs)
85
86    for k in range(0,len(hex_blobs)):
[40]87        hex = hex_blobs[k].decode()
[1]88       
[9]89        for i in range(0,len(hex),line_size):
[13]90            line = '%.4X: ' % i
[1]91
[9]92            if len(hex[i:]) < line_size:
93                hex += (line_size-len(hex[i:]))*' '
[1]94
[9]95            for j in range(0,line_size,group_size):
96                group = hex[i+j:i+j+group_size]
[46]97                line += terminalHighlightedString(color_map.get(group.encode('utf-8'),
98                                                                None), group) + ' ' 
[9]99       
[1]100            line += '| '
[40]101            line += repr(blobs[k][i//2:(i+line_size)//2])
[1]102       
[9]103            print(line)
104        print('')
[1]105
106
107
108def analyze(blobs):
109    lengths = blobtools.getLengths(blobs)
110    print('Unique Lengths: ' + ','.join(map(str, lengths)))
111
112    max_block_size = blobtools.maxBlockSize(lengths)
113    print('Maximum Possible Block Size: %d' % max_block_size)
114
115    block_sizes = blobtools.checkCommonBlocksizes(lengths)
116    print('Matching Common Block Sizes: %s' % ','.join(map(str, block_sizes)))
117
118    encodings = blobtools.encodingIntersection(blobs)
119    print('Possible Encodings: ' + ','.join(encodings))
120
121    encoding = blobtools.bestEncoding(encodings)
122    print('Best Encoding: %s' % encoding)
123
124    return encoding,block_sizes
125
[13]126specified_encodings = []
127if options.encoding_chain != None:
128    specified_encodings = options.encoding_chain.split(',')
[1]129
130encoding_chain = []
131encoding = 'dummy'
132while encoding != None:
133    print('='*80)
134    print('Beginning analysis after decoding by chain: %s' % ','.join(encoding_chain))
135    encoding,block_sizes = analyze(blobs)
[13]136    if len(specified_encodings) > 0:
137        encoding = specified_encodings.pop(0)
[1]138
139    blobs_to_print = blobs[:options.output_lines]
140    print('First %d Values:' % len(blobs_to_print))
141
[13]142    printColoredHexDump(blobs_to_print, options.block_size)
[1]143
144    if encoding != None:
145        encoding_chain.append(encoding)
146        blobs = blobtools.decodeAll(encoding, blobs)
147
Note: See TracBrowser for help on using the repository browser.