def website( url=r'http://crypto-class.appspot.com/po?er=f20bdba6ff29eed7b046d1df9fb7000058b1ffb4210a580f748b4ac714c001bd4a61044426fb515dad3f21f18aa577c0bdf302936266926ff37dbf7035d5eeb4', mode='CBC', get_regex=r'\w*[?][a-zA-Z]+[=]', block_size=16, last_m='are Squeamish Ossifrage\t\t\t\t\t\t\t\t\t', guesses=count_frequencies()): N_known = len(last_m) rest_getter = re.search(get_regex, url).group() print rest_getter base_url, c = url.split(rest_getter) print base_url, c # discard the last block? don't need to do this, just following example first c = c.decode('hex') print len(c) N = len(c) BS = block_size m = ['_'] * (N - N_known) + list(last_m) for j in range(N_known, N): SLB0 = N - (((j / BS) + 2) * BS) SLBN = N - (((j / BS) + 1) * BS) SLBi = N - j - BS - 1 LB0 = SLB0 + BS LBN = SLBN + BS LBi = SLBi + BS print j, SLB0, SLBi, SLBN, LB0, LBi, LBN LBhex = c[LB0:LBN].encode('hex') SLB_prefix = chr(0) * (SLBi - SLB0) SLB_suffix = ''.join(m[(LBi + 1):LBN]) cSLB_suffix = c[SLBi:SLBN] pad = chr((j % BS) + 1) * ((j % BS) + 1) print '%r: %r' % (j, (SLB_prefix + chr(0) + SLB_suffix).encode('hex') + LBhex) print '%r: %r' % (j, (SLB_prefix + pad).encode('hex') + LBhex) print '%r: %r' % ( j, (SLB_prefix + strxor(chr(0) + SLB_suffix, pad)).encode('hex') + LBhex) for i in range(len(guesses)): g = guesses[i] SLB_guess = strxor(cSLB_suffix, strxor(g + SLB_suffix, pad)) guess_hex = (c[:SLBi] + SLB_guess).encode('hex') + LBhex new_url = base_url + rest_getter + guess_hex response = urllib.urlopen(new_url) print repr(g), '->', response.getcode(), new_url if padding_oracle(response): print '%dth character (%d from end) is chr(%d) = %r' % (LBi, j, i, g) break m[LBi] = g print repr(''.join(m)) return ''.join(m)
def website(url=r'http://crypto-class.appspot.com/po?er=f20bdba6ff29eed7b046d1df9fb7000058b1ffb4210a580f748b4ac714c001bd4a61044426fb515dad3f21f18aa577c0bdf302936266926ff37dbf7035d5eeb4', mode='CBC', get_regex=r'\w*[?][a-zA-Z]+[=]', block_size=16, last_m = 'are Squeamish Ossifrage\t\t\t\t\t\t\t\t\t', guesses = count_frequencies() ): N_known = len(last_m) rest_getter = re.search(get_regex, url).group() print rest_getter base_url, c = url.split(rest_getter) print base_url, c # discard the last block? don't need to do this, just following example first c = c.decode('hex') print len(c) N = len(c) BS = block_size m = ['_'] * (N - N_known) + list(last_m) for j in range(N_known, N): SLB0 = N-(((j/BS)+2)*BS) SLBN = N-(((j/BS)+1)*BS) SLBi = N-j-BS-1 LB0 = SLB0 + BS LBN = SLBN + BS LBi = SLBi + BS print j, SLB0, SLBi, SLBN, LB0, LBi, LBN LBhex = c[LB0:LBN].encode('hex') SLB_prefix = chr(0) * (SLBi - SLB0) SLB_suffix = ''.join(m[(LBi+1):LBN]) cSLB_suffix = c[SLBi:SLBN] pad = chr((j%BS)+1) * ((j%BS)+1) print '%r: %r' % (j, (SLB_prefix + chr(0) + SLB_suffix).encode('hex') + LBhex) print '%r: %r' % (j, (SLB_prefix + pad).encode('hex') + LBhex) print '%r: %r' % (j, (SLB_prefix + strxor(chr(0) + SLB_suffix, pad)).encode('hex') + LBhex) for i in range(len(guesses)): g = guesses[i] SLB_guess = strxor(cSLB_suffix, strxor(g + SLB_suffix, pad)) guess_hex = (c[:SLBi] + SLB_guess).encode('hex') + LBhex new_url = base_url + rest_getter + guess_hex response = urllib.urlopen(new_url) print repr(g), '->', response.getcode(), new_url if padding_oracle(response): print '%dth character (%d from end) is chr(%d) = %r' % (LBi, j, i, g) break m[LBi] = g print repr(''.join(m)) return ''.join(m)
def inject(cypher_text=r'20814804c1767293b99f1d9cab3bc3e7ac1e37bfb15599e5f40eef805488281d', plain_text=r' 1 ', desired_plain_text=r' 5 ', block_size=16, mode='CBC'): '''Produce the cyphertext for the requested plain text message without know the key! >>> m = 'Hello World.' >>> D(k, inject(E(k, m), m, 'Hello Ralph.')) 'Hello Ralph.' ''' if not mode.lower().strip() == 'cbc': raise NotImplementedError('I only know how to *fix* CBC-authenticated messages.') hex_cypher_text = cypher_text IV = hex_cypher_text.decode('hex')[:block_size] # add zero pad for any text (pad) that you don't want modified plain_text += '\x00' * (block_size - len(plain_text)) desired_plain_text += '\x00' * (block_size - len(desired_plain_text)) IV2 = strxor(strxor(IV, plain_text), desired_plain_text) return IV2.encode('hex') + hex_cypher_text[len(IV2)*2:]
def inject( cypher_text=r'20814804c1767293b99f1d9cab3bc3e7ac1e37bfb15599e5f40eef805488281d', plain_text=r' 1 ', desired_plain_text=r' 5 ', block_size=16, mode='CBC'): '''Produce the cyphertext for the requested plain text message without know the key! >>> m = 'Hello World.' >>> D(k, inject(E(k, m), m, 'Hello Ralph.')) 'Hello Ralph.' ''' if not mode.lower().strip() == 'cbc': raise NotImplementedError( 'I only know how to *fix* CBC-authenticated messages.') hex_cypher_text = cypher_text IV = hex_cypher_text.decode('hex')[:block_size] # add zero pad for any text (pad) that you don't want modified plain_text += '\x00' * (block_size - len(plain_text)) desired_plain_text += '\x00' * (block_size - len(desired_plain_text)) IV2 = strxor(strxor(IV, plain_text), desired_plain_text) return IV2.encode('hex') + hex_cypher_text[len(IV2) * 2:]