Changeset 40
- Timestamp:
- 03/17/13 22:26:27 (12 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SConstruct
r26 r40 65 65 # env.AddPostAction(libinstall, 'ldconfig') 66 66 67 if sys.version_info[0] == 2:68 install_items.append('bletchley-python2.log')69 env.Command('bletchley-python2.log', Glob('lib/bletchley/*.py')+Glob('lib/bletchley/CBC/*.py'),70 "python bletchley-distutils install --root=/%s | tee bletchley-python2.log" % destdir)67 #if sys.version_info[0] == 2: 68 # install_items.append('bletchley-python2.log') 69 # env.Command('bletchley-python2.log', Glob('lib/bletchley/*.py')+Glob('lib/bletchley/CBC/*.py'), 70 # "python bletchley-distutils install --root=/%s | tee bletchley-python2.log" % destdir) 71 71 72 72 python_path = os.popen('which python3').read() -
trunk/bin/bletchley-analyze
r35 r40 1 #!/usr/bin/env python 1 #!/usr/bin/env python3 2 2 3 # Requires Python 2.7+3 # Requires Python 3+ 4 4 5 5 ''' … … 54 54 sys.exit(0) 55 55 56 input_file = sys.stdin 56 input_file = sys.stdin.buffer 57 57 if options.input_file is not None: 58 input_file = file(options.input_file, 'rb')58 input_file = open(options.input_file, 'rb') 59 59 60 blobs = input_file.read().rstrip( '\n').replace('\r', '').split('\n')60 blobs = input_file.read().rstrip(b'\n').replace(b'\r', b'').split(b'\n') 61 61 #print(repr(blobs)) 62 62 … … 81 81 line_size = 64 82 82 group_size *= 2 # two hex digits per byte 83 hex_blobs = map(binascii.b2a_hex, blobs)83 hex_blobs = [binascii.b2a_hex(b) for b in blobs] 84 84 color_map = buffertools.blockWiseColorMap(group_size, hex_blobs) 85 85 86 86 for k in range(0,len(hex_blobs)): 87 hex = hex_blobs[k] 87 hex = hex_blobs[k].decode() 88 88 89 89 for i in range(0,len(hex),line_size): … … 98 98 99 99 line += '| ' 100 line += repr(blobs[k][i/ 2:(i+line_size)/2])100 line += repr(blobs[k][i//2:(i+line_size)//2]) 101 101 102 102 print(line) … … 136 136 encoding = specified_encodings.pop(0) 137 137 138 139 138 blobs_to_print = blobs[:options.output_lines] 140 139 print('First %d Values:' % len(blobs_to_print)) -
trunk/bin/bletchley-decode
r28 r40 1 #!/usr/bin/env python 1 #!/usr/bin/env python3 2 2 3 # Requires Python 2.7+3 # Requires Python 3+ 4 4 5 5 ''' … … 45 45 sys.exit(0) 46 46 47 input_file = sys.stdin 47 input_file = sys.stdin.buffer 48 48 if options.input_file is not None: 49 input_file = file(options.input_file, 'rb')49 input_file = open(options.input_file, 'rb') 50 50 51 blob = input_file.read() 51 blob = input_file.read().rstrip(b'\r\n') 52 52 53 53 specified_encodings = options.encoding_chain.split(',') 54 sys.stdout. write(blobtools.decodeChain(specified_encodings, blob))54 sys.stdout.buffer.write(blobtools.decodeChain(specified_encodings, blob)) -
trunk/bin/bletchley-encode
r28 r40 1 #!/usr/bin/env python 1 #!/usr/bin/env python3 2 2 3 # Requires Python 2.7+3 # Requires Python 3+ 4 4 5 5 ''' … … 46 46 sys.exit(0) 47 47 48 input_file = sys.stdin 48 input_file = sys.stdin.buffer 49 49 if options.input_file is not None: 50 50 input_file = file(options.input_file, 'rb') … … 55 55 specified_encodings.reverse() 56 56 # XXX: report invalid encodings 57 sys.stdout. write(blobtools.encodeChain(specified_encodings, blob))58 sys.stdout. write('\n')57 sys.stdout.buffer.write(blobtools.encodeChain(specified_encodings, blob)) 58 sys.stdout.buffer.write(b'\n') -
trunk/bin/bletchley-http2py
r39 r40 1 #!/usr/bin/env python 2 3 # Requires Python 2.7+1 #!/usr/bin/env python3 2 3 # Requires Python 3+ 4 4 5 5 ''' 6 This script reads a raw HTTP request from stdin and writes to stdout 7 a Python script. The generated script sends the same (or a very similar) 8 request using the httplib/http.client libraries. 6 This script reads a raw HTTP request and writes to stdout a Python 7 script. The generated script sends the same (or a very similar) 8 request using the standard httplib/http.client library, or optionally 9 using the more user friendly python-requests library. 9 10 10 11 Certainly if you have a raw request, you could simply send it via TCP … … 34 35 import sys 35 36 import argparse 36 try:37 from lxml import etree38 except:39 sys.stderr.write('ERROR: Could not import lxml module. Ensure it is installed.\n')40 sys.stderr.write(' Under Debian, the package name is "python-lxml"\n.')41 sys.exit(1)42 37 43 38 parser = argparse.ArgumentParser( … … 48 43 ' For more information, see: http://code.google.com/p/bletchley/wiki/Overview') 49 44 parser.add_argument( 50 'requestfile', type= file, nargs='?', default=sys.stdin,45 'requestfile', type=open, nargs='?', default=sys.stdin, 51 46 help='A file containing an HTTP request. Defaults to stdin if omitted.') 52 47 parser.add_argument( 53 '--burp', action='store_true', help='Input file is a XML export from Burp.' 54 ' (First request in file is used.)') 48 '--requests', action='store_true', help='Generate a script that uses the' 49 ' python-requests module rather than httplib/http.client (experimental).') 50 55 51 args = parser.parse_args() 56 57 if args.burp: 58 safe_parser = etree.ETCompatXMLParser(resolve_entities=False) 59 root = etree.parse(args.requestfile, parser=safe_parser) 60 input_req = root.xpath('/items/item/request')[0].text 61 root = None 62 else: 63 input_req = args.requestfile.read() 64 52 input_req = args.requestfile.read() 65 53 66 54 … … 79 67 port = 80 80 68 use_ssl = False 69 protocol = 'http' 81 70 82 71 headers = [] … … 85 74 break 86 75 # Handle header line continuations 87 if l[0] == '\t':76 if l[0] in ' \t': 88 77 if len(headers) == 0: 89 78 continue … … 108 97 if port == 443: 109 98 use_ssl = True 99 protocol = 'https' 110 100 else: 111 101 host = value 112 102 113 103 114 print('''#!/usr/bin/env python 104 formatted_body = '\n '.join([repr(body[i:i+40].encode()) for i in range(0,len(body),40)]) 105 if formatted_body == '': 106 formatted_body = "b''" 107 108 109 if args.requests: 110 print('''#!/usr/bin/env python3 115 111 116 112 import sys 117 # function with either Python 2.7 or 3.x118 113 try: 119 import http.client as httpc114 import requests 120 115 except: 121 import httplib as httpc 116 sys.stderr.write('ERROR: Could not import requests module. Ensure it is installed.\\n') 117 sys.stderr.write(' Under Debian, the package name is "python3-requests"\\n.') 118 sys.exit(1) 119 120 121 # TODO: ensure the host, port, and SSL settings are correct. 122 host = %s 123 port = %s 124 protocol = %s 125 ''' % (repr(host),repr(port),repr(protocol))) 126 127 headers = dict(headers) 128 # XXX: We don't currently support exactly formatted header 129 # continuations with python requests, but this should be 130 # semantically equivalent. 131 for h in headers.keys(): 132 headers[h] = ' '.join(headers[h]) 133 134 print(''' 135 session = requests.Session() 136 # TODO: use "data" to supply any parameters to be included in the request 137 def sendRequest(session, data=None): 138 method = %s 139 path = %s 140 headers = %s 141 url = "%%s://%%s:%%d%%s" %% (protocol,host,port,path) 142 body = (%s) 143 144 return session.request(method, url, headers=headers, data=body) 145 ''' % (repr(method), repr(path), repr(headers), formatted_body)) 146 147 print(''' 148 149 def fetch(data): 150 global session 151 ret_val = None 152 153 # TODO: customize code here to retrieve what you need from the response(s) 154 # For information on the response object's interface, see: 155 # http://docs.python-requests.org/en/latest/api/#requests.Response 156 response = sendRequest(session, data) 157 print(response.headers) 158 print(repr(response.content)) 159 160 return ret_val 161 162 data = '' 163 fetch(data) 122 164 ''') 123 165 124 166 125 print(''' 167 168 else: 169 print('''#!/usr/bin/env python3 170 171 import sys 172 import http.client as httpc 173 174 126 175 # TODO: ensure the host, port, and SSL settings are correct. 127 176 host = %s … … 130 179 ''' % (repr(host),repr(port),repr(use_ssl))) 131 180 132 chunked_body = '\n '.join([repr(body[i:i+40]) for i in range(0,len(body),40)]) 133 if chunked_body == '': 134 chunked_body = "''" 135 136 print(''' 181 print(''' 137 182 # TODO: use "data" to supply any parameters to be included in the request 138 183 def sendRequest(connection, data=None): … … 142 187 143 188 connection.putrequest(method, path) 144 ''' % (repr(method), repr(path), chunked_body))145 146 for name,values in headers:147 if len(values) > 1:148 continuations = ','.join([repr(v) for v in values[1:]])149 print(''' connection.putheader(%s, %s, %s)''' % (repr(name),repr(values[0]),continuations))150 else:151 print(''' connection.putheader(%s, %s)''' % (repr(name),repr(values[0])))152 153 print('''189 ''' % (repr(method), repr(path), formatted_body)) 190 191 for name,values in headers: 192 if len(values) > 1: 193 continuations = ','.join([repr(v) for v in values[1:]]) 194 print(''' connection.putheader(%s, %s, %s)''' % (repr(name),repr(values[0]),continuations)) 195 else: 196 print(''' connection.putheader(%s, %s)''' % (repr(name),repr(values[0]))) 197 198 print(''' 154 199 if len(body) > 0: 155 200 connection.putheader('Content-Length', len(body)) … … 161 206 162 207 def newConnection(): 163 connection = None164 208 if use_ssl: 165 209 return httpc.HTTPSConnection(host, port) -
trunk/lib/bletchley/blobtools.py
r35 r40 22 22 import base64 23 23 import binascii 24 import urllib25 24 import fractions 26 25 import operator 27 26 import functools 28 27 import itertools 29 import buffertools 28 from . import buffertools 29 30 31 # urllib.parse's functions are not well suited for encoding/decoding 32 # bytes or managing encoded case 33 def _percentEncode(binary, plus=False, upper=True): 34 fmt = "%%%.2X" 35 if upper: 36 fmt = "%%%.2x" 37 38 ret_val = b'' 39 for c in binary: 40 if c not in b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789': 41 ret_val += (fmt % c).encode('ascii') 42 elif plus and (c == 20): 43 ret_val += b'+' 44 else: 45 ret_val += c 46 47 return ret_val 48 49 50 def _percentDecode(binary, plus=False): 51 ret_val = b'' 52 if plus: 53 binary = binary.replace(b'+', b' ') 54 if binary == b'': 55 return b'' 56 chunks = binary.split(b'%') 57 if binary[0] == 0x25: 58 chunks = chunks[1:] 59 60 for chunk in chunks: 61 if len(chunk) < 2: 62 return None 63 try: 64 ret_val += bytes([int(chunk[0:2], 16)]) + chunk[2:] 65 except: 66 print(repr(chunk)) 67 return None 68 69 return ret_val 70 30 71 31 72 # abstract class 32 73 class DataEncoding(object): 33 charset = frozenset( '')34 extraneous_chars = ''74 charset = frozenset(b'') 75 extraneous_chars = b'' 35 76 dialect = None 36 77 name = None … … 65 106 super(base64Encoding, self).__init__(dialect) 66 107 if dialect.startswith('rfc3548'): 67 self.c62 = '+'68 self.c63 = '/'69 self.pad = '='108 self.c62 = b'+' 109 self.c63 = b'/' 110 self.pad = b'=' 70 111 elif dialect.startswith('filename'): 71 self.c62 = '+'72 self.c63 = '-'73 self.pad = '='112 self.c62 = b'+' 113 self.c63 = b'-' 114 self.pad = b'=' 74 115 elif dialect.startswith('url1'): 75 self.c62 = '-'76 self.c63 = '_'77 self.pad = '='116 self.c62 = b'-' 117 self.c63 = b'_' 118 self.pad = b'=' 78 119 elif dialect.startswith('url2'): 79 self.c62 = '-'80 self.c63 = '_'81 self.pad = '.'120 self.c62 = b'-' 121 self.c63 = b'_' 122 self.pad = b'.' 82 123 elif dialect.startswith('url3'): 83 self.c62 = '_'84 self.c63 = '-'85 self.pad = '.'124 self.c62 = b'_' 125 self.c63 = b'-' 126 self.pad = b'.' 86 127 elif dialect.startswith('url4'): 87 self.c62 = '-'88 self.c63 = '_'89 self.pad = '!'128 self.c62 = b'-' 129 self.c63 = b'_' 130 self.pad = b'!' 90 131 elif dialect.startswith('url5'): 91 self.c62 = '+'92 self.c63 = '/'93 self.pad = '$'132 self.c62 = b'+' 133 self.c63 = b'/' 134 self.pad = b'$' 94 135 elif dialect.startswith('otkurl'): 95 self.c62 = '-'96 self.c63 = '_'97 self.pad = '*'136 self.c62 = b'-' 137 self.c63 = b'_' 138 self.pad = b'*' 98 139 elif dialect.startswith('xmlnmtoken'): 99 self.c62 = '.'100 self.c63 = '-'101 self.pad = '='140 self.c62 = b'.' 141 self.c63 = b'-' 142 self.pad = b'=' 102 143 elif dialect.startswith('xmlname'): 103 self.c62 = '_'104 self.c63 = ':'105 self.pad = '='144 self.c62 = b'_' 145 self.c63 = b':' 146 self.pad = b'=' 106 147 107 148 if 'newline' in dialect: 108 self.extraneous_chars = '\r\n'109 110 self.charset = frozenset( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'111 + 'abcdefghijklmnopqrstuvwxyz0123456789'149 self.extraneous_chars = b'\r\n' 150 151 self.charset = frozenset(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 152 +b'abcdefghijklmnopqrstuvwxyz0123456789' 112 153 +self.c62+self.c63+self.pad+self.extraneous_chars) 113 154 … … 120 161 def extraTests(self, blob): 121 162 for c in self.extraneous_chars: 122 blob = blob.replace( c,'')163 blob = blob.replace(bytes([c]), b'') 123 164 124 165 nopad = blob.rstrip(self.pad) … … 137 178 def decode(self, blob): 138 179 for c in self.extraneous_chars: 139 blob = blob.replace( c,'')180 blob = blob.replace(bytes(c), b'') 140 181 141 182 if self.dialect.endswith('nopad'): … … 150 191 151 192 if not self.dialect.startswith('rfc3548'): 152 table = string.maketrans(self.c62+self.c63+self.pad, '+/=')193 table = string.maketrans(self.c62+self.c63+self.pad, b'+/=') 153 194 blob = blob.translate(table) 154 195 … … 160 201 161 202 if not self.dialect.startswith('rfc3548'): 162 table = string.maketrans( '+/=', self.c62+self.c63+self.pad)203 table = string.maketrans(b'+/=', self.c62+self.c63+self.pad) 163 204 ret_val = ret_val.translate(table) 164 205 … … 174 215 super(base32Encoding, self).__init__(dialect) 175 216 if dialect.startswith('rfc3548upper'): 176 self.pad = '='177 self.charset = frozenset( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'+self.pad)217 self.pad = b'=' 218 self.charset = frozenset(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'+self.pad) 178 219 179 220 elif dialect.startswith('rfc3548lower'): 180 self.pad = '='181 self.charset = frozenset( 'abcdefghijklmnopqrstuvwxyz234567'+self.pad)221 self.pad = b'=' 222 self.charset = frozenset(b'abcdefghijklmnopqrstuvwxyz234567'+self.pad) 182 223 183 224 def _guessPadLength(self, nopad_len): … … 203 244 if self.dialect.endswith('nopad'): 204 245 if self.pad in blob: 205 raise Exception("Unpadded base 64string contains pad character")246 raise Exception("Unpadded base32 string contains pad character") 206 247 207 248 padlen = self._guessPadLength(len(blob)) … … 233 274 super(hexEncoding, self).__init__(dialect) 234 275 if 'mixed' in dialect: 235 self.charset = frozenset( 'ABCDEFabcdef0123456789')276 self.charset = frozenset(b'ABCDEFabcdef0123456789') 236 277 elif 'upper' in dialect: 237 self.charset = frozenset( 'ABCDEF0123456789')278 self.charset = frozenset(b'ABCDEF0123456789') 238 279 elif 'lower' in dialect: 239 self.charset = frozenset( 'abcdef0123456789')280 self.charset = frozenset(b'abcdef0123456789') 240 281 241 282 … … 261 302 self.charset = None 262 303 if 'mixed' in dialect: 263 self.hexchars = frozenset( 'ABCDEFabcdef0123456789')304 self.hexchars = frozenset(b'ABCDEFabcdef0123456789') 264 305 elif 'upper' in dialect: 265 self.hexchars = frozenset( 'ABCDEF0123456789')306 self.hexchars = frozenset(b'ABCDEF0123456789') 266 307 elif 'lower' in dialect: 267 self.hexchars = frozenset( 'abcdef0123456789')308 self.hexchars = frozenset(b'abcdef0123456789') 268 309 269 310 def extraTests(self, blob): 270 chunks = blob.split( '%')311 chunks = blob.split(b'%') 271 312 if len(chunks) < 2: 272 313 return None … … 279 320 280 321 def decode(self, blob): 322 plus = False 281 323 if 'plus' in self.dialect: 282 return urllib.unquote(blob) 283 else: 284 return urllib.unquote_plus(blob) 285 286 # XXX: should technically produce quoted digits in same upper/lower case 324 plus = True 325 return _percentDecode(blob, plus=plus) 326 287 327 def encode(self, blob): 328 upper = True 329 plus = False 288 330 if 'plus' in self.dialect: 289 return urllib.quote(blob, '') 290 else: 291 return urllib.quote_plus(blob, '') 331 plus = True 332 if 'lower' in self.dialect: 333 upper = False 334 335 return _percentEncode(blob, plus=plus, upper=upper) 292 336 293 337 … … 336 380 337 381 def supportedEncodings(): 338 e = encodings.keys()382 e = list(encodings.keys()) 339 383 e.sort() 340 384 return e … … 380 424 381 425 def decodeAll(encoding, blobs): 382 return map(encodings[encoding].decode, blobs)426 return [encodings[encoding].decode(b) for b in blobs] 383 427 384 428 def encodeAll(encoding, blobs): 385 return map(encodings[encoding].encode, blobs)429 return [encodings[encoding].encode(b) for b in blobs] 386 430 387 431 def decodeChain(decoding_chain, blob): … … 412 456 413 457 414 allTrue = functools.partial( reduce, (lambda x,y: x and y))458 allTrue = functools.partial(functools.reduce, (lambda x,y: x and y)) 415 459 416 460 def checkCommonBlocksizes(lengths): -
trunk/lib/bletchley/buffertools.py
r36 r40 75 75 76 76 colors = {} 77 for block,count in block_counts.ite ritems():77 for block,count in block_counts.items(): 78 78 if count == 1: 79 79 # mask needed for portability
Note: See TracChangeset
for help on using the changeset viewer.