source: bin/bletchley-analyze @ 4

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

moved to dedicated repository

  • Property svn:executable set to *
File size: 4.2 KB
RevLine 
[1]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    chunk_size = 64
69    group_size *= 2 # two hex digits per byte
70
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        line = ''
77       
78        for i in range(0,len(hex),chunk_size):
79            line += '%.8X: ' % i
80
81            if len(hex) < chunk_size:
82                hex += (chunk_size-len(hex))*' '
83
84            for j in range(0,len(hex),group_size):
85                group = hex[j:j+group_size]
86                line += terminalHighlightedString(color_map.get(group, None), group) + ' '
87       
88            line += '| '
89            line += repr(blobs[k][i/2:(i+chunk_size)/2])
90            line += '\n'
91       
92        print(line)
93
94
95
96def analyze(blobs):
97    lengths = blobtools.getLengths(blobs)
98    print('Unique Lengths: ' + ','.join(map(str, lengths)))
99
100    max_block_size = blobtools.maxBlockSize(lengths)
101    print('Maximum Possible Block Size: %d' % max_block_size)
102
103    block_sizes = blobtools.checkCommonBlocksizes(lengths)
104    print('Matching Common Block Sizes: %s' % ','.join(map(str, block_sizes)))
105
106    encodings = blobtools.encodingIntersection(blobs)
107    print('Possible Encodings: ' + ','.join(encodings))
108
109    encoding = blobtools.bestEncoding(encodings)
110    print('Best Encoding: %s' % encoding)
111
112    return encoding,block_sizes
113
114
115encoding_chain = []
116encoding = 'dummy'
117while encoding != None:
118    print('='*80)
119    print('Beginning analysis after decoding by chain: %s' % ','.join(encoding_chain))
120    encoding,block_sizes = analyze(blobs)
121    group_size = 4
122    if len(block_sizes) > 0 and min(block_sizes) in (8,16):
123        group_size = min(block_sizes)
124
125    blobs_to_print = blobs[:options.output_lines]
126    print('First %d Values:' % len(blobs_to_print))
127
128    printColoredHexDump(blobs_to_print, group_size)
129
130    if encoding != None:
131        encoding_chain.append(encoding)
132        blobs = blobtools.decodeAll(encoding, blobs)
133
Note: See TracBrowser for help on using the repository browser.