Ignore:
Timestamp:
10/17/13 12:10:35 (11 years ago)
Author:
tmorgan
Message:

added result set object and HTML generator to chosenct probe routine

Python3 fixes and code reorganization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/bletchley/chosenct.py

    r50 r65  
    2323import struct
    2424import queue
     25import hashlib
     26
     27# Wish Python had a better function for this that escaped more characters
     28_html_escape_table = {
     29    "&": "&",
     30    '"': """,
     31    "'": "'",
     32    ">": ">",
     33    "<": "&lt;",
     34    "\n": "&#x0a",
     35    "\r": "&#x0d",
     36    }
     37
     38def _html_escape(text):
     39    return "".join(_html_escape_table.get(c,c) for c in text)
     40
     41
     42class ProbeResults:
     43    '''TODO
     44    '''
     45    _values = None
     46    _raw_table = None #indexes are byte offset, then XORed value
     47    _messages = None
     48    _html_header = """<head>
     49<script>
     50function displayMessage(id)
     51{
     52  alert(document.getElementById(id).value);
     53}
     54</script>
     55<style>
     56td
     57{
     58  border-style: solid;
     59  border-width: medium;
     60  border-color: #FFFFFF;
     61  border-spacing: 0px;
     62  min-width: 100px;
     63  max-width: 100px;
     64  word-wrap: break-word;
     65}
     66</style></head>"""
     67
     68   
     69    def __init__(self, ct_length, values):
     70        self._ct_length = ct_length
     71        self._values = values
     72        self._raw_table = {}
     73        self._messages = {}
     74        return
     75
     76    def _generate_colors(self, s):
     77        base=bytes(hashlib.md5(s).digest()[0:6])
     78        color1 = "#%.2X%.2X%.2X" % tuple(base[:3])
     79        color2 = "#%.2X%.2X%.2X" % tuple(base[3:])
     80
     81        return color1,color2
     82
     83
     84    def toHTML(self):
     85        maxlen = 20
     86        ret_val = self._html_header
     87        ret_val += '<table><tr><td>&nbsp;&nbsp;&nbsp;OFFSET<br /><br />VALUE</td>'
     88
     89        for offset in self._raw_table.keys():
     90            ret_val += '<td>%d<br /><br /></td>' % offset
     91        ret_val += '</tr>'
     92
     93        for v in self._values:
     94            ret_val += '<tr><td>0x%.2X</td>' % v
     95            for offset in range(0,self._ct_length):
     96                message = self._raw_table[offset][v]
     97                bg,fg = self._generate_colors(message)
     98                message = message.decode('utf-8')
     99
     100                truncated = message[0:maxlen]
     101                if len(message) > maxlen:
     102                    truncated += '...'
     103                msg_id = 'cell_%.2X_%.2X' % (offset, v)
     104                ret_val += ('''<td style="background-color:%s; border-color:%s" onclick="displayMessage('%s')">'''
     105                            '''<input type="hidden" id="%s" value="%s" />%s</td>\n''')\
     106                            % (bg,fg, msg_id, msg_id, _html_escape(message), _html_escape(truncated))
     107            ret_val += '</tr>'
     108           
     109        ret_val += '</table>'
     110
     111        return ret_val
     112
    25113
    26114def probe_bytes(checker, ciphertext, values, max_threads=1):
     
    29117    error message was generated.
    30118
    31     TODO
     119    Arguments:
     120    checker -- A function which sends a specified ciphertext to the targeted
     121               application and returns a string describing the kind of response
     122               that was encountered.  This function should be thread-safe when
     123               max_threads > 1.
     124
     125               This function should implement the prototype:
     126                 def myChecker(ciphertext): ...
     127
     128               The function should return strings that are relevant to
     129               the kind of overall response generated by the targeted
     130               system or application.  For instance, if detailed error
     131               messages are returned, then the important parts of those
     132               errors should be returned.  If error messages are not
     133               returned in some cases, then simple tokens that describe
     134               the behavior of the response should suffice.  For
     135               instance, if in some cases the application returns a
     136               generic HTTP 500 error, in other cases it drops the TCP
     137               connection, and still in other cases it doesn't return an
     138               error, then the checker function could return "500",
     139               "dropped", and "success" respectively for those cases.
     140
     141    ciphertext -- A ciphertext buffer (bytes/bytearray) that will be repeatedly
     142               modified and tested using the checker function.
     143
     144    values --  A sequence of integers in the range [0..255].  These values
     145               will be XORed with each byte in the ciphertext and tested, one
     146               after another.  To make a single change to each byte in the
     147               ciphertext, provide something like [1].  To flip every bit
     148               in the entire ciphertext individually, supply: [1,2,4,8,16,32,64,128]
     149
     150    max_threads -- The maximum number of threads to run in parallel while
     151               testing modified ciphertexts.
    32152    '''
    33153    if max_threads < 1:
     
    37157    values = bytearray(values)
    38158
    39     ret_val = {}
     159    # XXX: Improve threading model
     160    #      Instead of forking threads and joining them for each byte,
     161    #      Generate all ciphertext variants up front, putting them in
     162    #      a jobs queue, and then have persistent threads pull from
     163    #      the jobs queue  (or use a generator, rather than a queue)
     164    ret_val = ProbeResults(len(ciphertext), values)
    40165    num_threads = min(len(values),max_threads)
    41166    threads = []
     
    56181            t.join()
    57182
    58         ret_val[j] = {}
     183        # XXX: add functions to ProbeResults class to add results here,
     184        #      rather than accessing members directly.
     185        ret_val._raw_table[j] = {}
    59186        while not results.empty():
    60             ret_val[j].update(results.get())
     187            ret_val._raw_table[j].update(results.get())
    61188
    62189    return ret_val
Note: See TracChangeset for help on using the changeset viewer.