source: trunk/bin/bletchley-analyze @ 115

Last change on this file since 115 was 115, checked in by tim, 8 years ago

256 color now default

  • Property svn:executable set to *
File size: 5.3 KB
Line 
1#!/usr/bin/env python3
2
3# Requires Python 3+
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(
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')
35parser.add_argument('input_file', nargs='?', default=None,
36                    help='File containing encrypted blobs to analyze, one per'
37                    ' line. Omit to read from stdin.')
38parser.add_argument('-e', dest='encoding_chain', type=str, default=None,
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.)')
42parser.add_argument('-b', dest='block_size', type=int, default=8,
43                    help='The block size displayed and used in highlighting (default: 8)')
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 mono output for decoded highlights.')
48parser.add_argument('-c', action='store_const', const=True, default=False,
49                    help='Use 8 color output for decoded highlights.')
50parser.add_argument('-c256', action='store_const', const=True, default=True,
51                    help='Use 256 color output for decoded highlights. (default)')
52options = parser.parse_args()
53
54if options.encoding_chain == '?':
55    print('\n\t'.join(['Supported encodings:']+blobtools.supportedEncodings()))
56    sys.exit(0)
57
58input_file = sys.stdin.buffer
59if options.input_file is not None:
60    input_file = open(options.input_file, 'rb')
61
62blobs = [b for b in input_file.read().rstrip(b'\n').replace(b'\r', b'').split(b'\n') if len(b) > 0]
63#print(repr(blobs))
64
65def terminalHighlightedString(code, s):
66    global options
67    if code == None:
68        return s
69
70    if options.C:
71        return "\x1b[7m%s\x1b[0m" % 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        fg = code%216+16
78        bg = (code^0xffffffff)%216+16
79        return "\x1b[0;38;05;%d;48;05;%dm%s\x1b[0m" % (fg,bg,s)
80
81
82def printColoredHexDump(blobs, group_size=8):   
83    line_size = 64
84    group_size *= 2 # two hex digits per byte
85    hex_blobs = [binascii.b2a_hex(b) for b in blobs]
86    color_map = buffertools.blockWiseColorMap(group_size, hex_blobs)
87
88    for k in range(0,len(hex_blobs)):
89        hex = hex_blobs[k].decode()
90       
91        for i in range(0,len(hex),line_size):
92            line = '%.4X: ' % i
93
94            if len(hex[i:]) < line_size:
95                hex += (line_size-len(hex[i:]))*' '
96
97            for j in range(0,line_size,group_size):
98                group = hex[i+j:i+j+group_size]
99                line += terminalHighlightedString(color_map.get(group.encode('utf-8'),
100                                                                None), group) + ' ' 
101       
102            line += '| '
103            line += repr(blobs[k][i//2:(i+line_size)//2])
104       
105            print(line)
106        print('')
107
108
109
110def analyze(blobs):
111    lengths = blobtools.getLengths(blobs)
112    print('Unique Lengths: ' + ','.join(map(str, lengths)))
113
114    max_block_size = blobtools.maxBlockSize(lengths)
115    print('Maximum Possible Block Size: %d' % max_block_size)
116
117    block_sizes = blobtools.checkCommonBlocksizes(lengths)
118    print('Matching Common Block Sizes: %s' % ','.join(map(str, block_sizes)))
119
120    encodings = blobtools.encodingIntersection(blobs)
121    print('Possible Encodings: ' + ','.join(encodings))
122
123    encoding = blobtools.bestEncoding(encodings)
124    print('Best Encoding: %s' % encoding)
125
126    return encoding,block_sizes
127
128specified_encodings = []
129if options.encoding_chain != None:
130    specified_encodings = options.encoding_chain.split(',')
131
132encoding_chain = []
133encoding = 'dummy'
134while encoding != None:
135    print('='*80)
136    print('Beginning analysis after decoding by chain: %s' % ','.join(encoding_chain))
137    encoding,block_sizes = analyze(blobs)
138    if len(specified_encodings) > 0:
139        encoding = specified_encodings.pop(0)
140
141    blobs_to_print = blobs[:options.output_lines]
142    print('First %d Values:' % len(blobs_to_print))
143
144    printColoredHexDump(blobs_to_print, options.block_size)
145
146    if encoding != None:
147        encoding_chain.append(encoding)
148        blobs = blobtools.decodeAll(encoding, blobs)
149
Note: See TracBrowser for help on using the repository browser.