source: bin/bletchley-analyze @ 9

Last change on this file since 9 was 9, checked in by tmorgan, 12 years ago

fixed problems with hexdump

  • Property svn:executable set to *
File size: 4.2 KB
Line 
1#!/usr/bin/env python
2
3# Requires Python 2.7+
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
31parser = argparse.ArgumentParser(description='Analyzes samples of encrypted data in an attempt to decode samples to binary and identify patterns useful in cryptanalysis.')
32parser.add_argument('input_file', nargs='?', default=None,
33                    help='File containing encrypted blobs to analyze, one per line. Omit to read from stdin.')
34parser.add_argument('-p', dest='output_lines', type=int, default=10,
35                    help='Number of lines of input to display in decoded form.')
36parser.add_argument('-c', action='store_const', const=True, default=False,
37                    help='Use color output for decoded highlights.')
38parser.add_argument('-c256', action='store_const', const=True, default=False,
39                    help='Use 256 color output for decoded highlights.')
40options = parser.parse_args()
41
42input_file = sys.stdin
43if options.input_file is not None:
44    input_file = file(options.input_file, 'rb')
45
46
47blobs = input_file.read().rstrip('\n').replace('\r', '').split('\n')
48#print(repr(blobs))
49
50def terminalHighlightedString(code, s):
51    global options
52    if code == None:
53        return s
54
55    if options.c256:
56        fg = code%216+16
57        bg = (code^0xffffffff)%216+16
58        return "\x1b[0;38;05;%d;48;05;%dm%s\x1b[0m" % (fg,bg,s)
59    elif options.c:
60        fg = code%6+31
61        bg = (code^0xffffffff)%6+41
62        return "\x1b[0;%d;%dm%s\x1b[0m" % (fg,bg,s)
63    else:
64        return "\x1b[7m%s\x1b[0m" % s
65
66
67def printColoredHexDump(blobs, group_size=8):   
68    line_size = 64
69    group_size *= 2 # two hex digits per byte
70    print(group_size)
71    hex_blobs = map(binascii.b2a_hex, blobs)
72    color_map = buffertools.blockWiseColorMap(group_size, hex_blobs)
73
74    for k in range(0,len(hex_blobs)):
75        hex = hex_blobs[k]
76       
77        for i in range(0,len(hex),line_size):
78            line = '%.8X: ' % i
79
80            if len(hex[i:]) < line_size:
81                hex += (line_size-len(hex[i:]))*' '
82
83            for j in range(0,line_size,group_size):
84                group = hex[i+j:i+j+group_size]
85                line += terminalHighlightedString(color_map.get(group, None), group) + ' ' 
86       
87            line += '| '
88            line += repr(blobs[k][i/2:(i+line_size)/2])
89       
90            print(line)
91        print('')
92
93
94
95def analyze(blobs):
96    lengths = blobtools.getLengths(blobs)
97    print('Unique Lengths: ' + ','.join(map(str, lengths)))
98
99    max_block_size = blobtools.maxBlockSize(lengths)
100    print('Maximum Possible Block Size: %d' % max_block_size)
101
102    block_sizes = blobtools.checkCommonBlocksizes(lengths)
103    print('Matching Common Block Sizes: %s' % ','.join(map(str, block_sizes)))
104
105    encodings = blobtools.encodingIntersection(blobs)
106    print('Possible Encodings: ' + ','.join(encodings))
107
108    encoding = blobtools.bestEncoding(encodings)
109    print('Best Encoding: %s' % encoding)
110
111    return encoding,block_sizes
112
113
114encoding_chain = []
115encoding = 'dummy'
116while encoding != None:
117    print('='*80)
118    print('Beginning analysis after decoding by chain: %s' % ','.join(encoding_chain))
119    encoding,block_sizes = analyze(blobs)
120    group_size = 4
121    if len(block_sizes) > 0 and min(block_sizes) in (8,16):
122        group_size = min(block_sizes)
123
124    blobs_to_print = blobs[:options.output_lines]
125    print('First %d Values:' % len(blobs_to_print))
126
127    printColoredHexDump(blobs_to_print, group_size)
128
129    if encoding != None:
130        encoding_chain.append(encoding)
131        blobs = blobtools.decodeAll(encoding, blobs)
132
Note: See TracBrowser for help on using the repository browser.