From abcab2a3a9187df74aeec5c1680862265b2dbe10 Mon Sep 17 00:00:00 2001 From: Orien Vandenbergh Date: Tue, 30 Aug 2016 17:40:53 -0600 Subject: [PATCH] Add in progress work --- python/foobar/three/hash_it_out.py | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 python/foobar/three/hash_it_out.py diff --git a/python/foobar/three/hash_it_out.py b/python/foobar/three/hash_it_out.py new file mode 100644 index 0000000..78b2e2e --- /dev/null +++ b/python/foobar/three/hash_it_out.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +""" +Hash it out +=========== + +Something horrible must have gone wrong in that last mission. As you wake in a holding cell, you realize that youre in the clutches of Professor Booleans numerous but relatively incompetent minions! Time to plan another escape. + +Lucky for you nobody is around (do these security minions just sleep all the time?), so you have a chance to examine your cell. Looking around, you see no signs of surveillance (ha, they must underestimate you already) and the only thing keeping you contained is an electronic door lock. Should be easy enough. + +You and Beta Rabbit worked together to exfiltrate some of Professor Booleans security information in anticipation of a moment just like this one. Time to put it to the test. + +If memory serves, this locking mechanism relies on a horribly bad cryptographic hash, and you should be able to break it with some rudimentary calculations. + +To open these doors, you will need to reverse engineer the hash function it is using. You already managed to steal the details of the algorithm used, and with some quiet observation of the guards you find out the results of the hash (the digest). Now to break it. + +The function takes a 16 byte input and gives a 16 byte output. It uses multiplication (*), bit-wise exclusive OR (XOR) and modulo (%) to calculate an element of the digest based on elements of the input message: + +digest [i] = ( (129 * message[i]) XOR message[i-1]) % 256 + +For the first element, the value of message[-1] is 0. + +For example, if message[0] - 1 and message[1] = 129, then: +For digest[0]: +129*message[0] = 129 +129 XOR message[-1] = 129 +129 % 256 = 129 +Thus digest[0] = 129. + +For digest[1]: +129*message[1] = 16641 +16641 XOR message[0] = 16640 +16640 % 256 = 0 +Thus digest[1] = 0. + +Write a function answer(digest) that takes an array of 16 integers and returns another array of 16 that correspond to the unique message that created this digest. Since each value is a single byte, the values are 0 to 255 for both message and digest. + +Test cases +========== + +Inputs: + (int list) digest = [0, 129, 3, 129, 7, 129, 3, 129, 15, 129, 3, 129, 7, 129, 3, 129] +Output: + (int list) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + +Inputs: + (int list) digest = [0, 129, 5, 141, 25, 137, 61, 149, 113, 145, 53, 157, 233, 185, 109, 165] +Output: + (int list) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225] +""" +inputs = [ + [0, 129, 3, 129, 7, 129, 3, 129, 15, 129, 3, 129, 7, 129, 3, 129], + [0, 129, 5, 141, 25, 137, 61, 149, 113, 145, 53, 157, 233, 185, 109, 165] + ] +solutions = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225] + ] + +def answer(const,digest): + results = [] + for idx in range(0,len(digest)): + results.append(calculate(const,idx,digest)) + + return results + +def calculate(const,idx,digest): + return (const * (previous(idx,digest) ^ digest[idx])) % 256 + return ((const * previous(idx,digest)) ^ digest[idx]) % 256 + return ((const * digest[idx]) ^ previous(idx,digest)) % 256 + +def previous(idx,digest): + return digest[idx-1] if idx>0 else 0 + +def evaluate(a,b): + if cmp(a,b)==0: + #print "True" + return True + else: + #print "False" + #print " ",a + #print " ",b + return False + +for x in range(0,256): + for i in range(0,len(solutions)): + result = answer(x,inputs[i]) + if evaluate(result,solutions[i]): + print "%d - Success" % ( x )