Advertisement
trmr

CSAW CTF 2014 feal writeup (2/2)

Feb 14th, 2016
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.95 KB | None | 0 0
  1. #!/usr/bin/env python  
  2. # -*- coding:utf-8 -*-  
  3. import hashlib, socket, os, subprocess  
  4. HOST, PORT = '127.0.0.1', 8888  
  5. NUM_CHECK = 10  
  6.  
  7. def sock(remoteip, remoteport):  
  8.     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
  9.     s.connect((remoteip, remoteport))  
  10.     return s, s.makefile('rw', bufsize=0)  
  11.  
  12. def read_until(f, delim='\n'):  
  13.     data = ''  
  14.     while not data.endswith(delim):  
  15.         data += f.read(1)  
  16.     return data  
  17.  
  18. ############################################################################################  
  19. def gBox(a,b,mode):  
  20.     x = (a+b+mode) & 0xff  
  21.     return ((x<<3)|(x>>5))&0xff  
  22.  
  23. def fBox(plain):  
  24.     t0 = (plain[2] ^ plain[3])  
  25.     y1 = gBox(plain[0] ^ plain[1], t0, 1)  
  26.     y0 = gBox(plain[0], y1, 0)  
  27.     y2 = gBox(t0, y1, 0)  
  28.     y3 = gBox(plain[3], y2, 1)  
  29.     return [y3, y2, y1, y0]  
  30.  
  31. def convert_list(input):  
  32.     return [(input&0xff), ((input>>8) & 0xff), ((input>>16) & 0xff), ((input>>24) & 0xff) ]  
  33.  
  34. def list_xor(*LIST):  
  35.     return map(lambda x: reduce(lambda a,b: a^b, x), zip(*LIST))  
  36.  
  37. def decrypt(plain,subkeys):  
  38.     cipherLeft = plain[0:4]  
  39.     cipherRight = plain[4:]  
  40.     R4R = list_xor(cipherLeft,cipherRight)  
  41.     R4L = list_xor(cipherLeft, fBox(list_xor(R4R, subkeys[3])))  
  42.     R3R = R4L  
  43.     R3L = list_xor(R4R , fBox(list_xor(R3R, subkeys[2])))  
  44.     R2R = R3L  
  45.     R2L = list_xor(R3R, fBox(list_xor(R2R, subkeys[1])))  
  46.     left = list_xor(R2R, fBox(list_xor(R2L, subkeys[0])))  
  47.     right = list_xor(left, R2L)  
  48.     pleft = list_xor(left, subkeys[4])  
  49.     pright = list_xor(right, subkeys[5])  
  50.     return pleft+pright  
  51.  
  52. ############################################################################################  
  53. def chal(f):  
  54.     read_until(f,"21 bytes, starting with ")  
  55.     prefix = f.read(16)  
  56.     i = 0  
  57.     while True:  
  58.       cand = prefix + ("%010x"%i).decode("hex")  
  59.       if hashlib.sha1(cand).hexdigest().endswith("ffff"):  
  60.         break  
  61.       i += 1  
  62.     f.write(cand)  
  63.  
  64. def get_keycipher(f):  
  65.     read_until(f,"Please decrypt: ")  
  66.     keycipher = f.read(32)  
  67.     read_until(f, "\n")  
  68.     return keycipher.decode("hex")  
  69.  
  70. def get_ciphertext(f, a):  
  71.     assert len(a) % 8 == 0  
  72.     f.write(''.join(map(chr, a)))  
  73.     C = f.read(16)  
  74.     read_until(f, "\n")  
  75.     return C  
  76.  
  77. def get_plaintext(diff_list):  
  78.     a = map(ord, os.urandom(8))  
  79.     b = list_xor(a, diff_list)  
  80.     return a, b  
  81.  
  82. def wrapper(cmd):  
  83.   print cmd  
  84.   p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)  
  85.   return p.communicate()[0]  
  86.  
  87. ############################################################################################  
  88. os.system("gcc -O3 test.c")  
  89.  
  90. s, f = sock(HOST, PORT)  
  91. chal(f)  
  92. key_cipher = get_keycipher(f)  
  93. print "[+] key_cipher=%s" % key_cipher.encode("hex")  
  94.  
  95. print "[+] recovering subkey3..."  
  96. diff_list, args = [0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00], ["3"]  
  97. for x in xrange(NUM_CHECK):  
  98.     a, b = get_plaintext(diff_list)  
  99.     args += [''.join(map(chr, a)).encode("hex")]  
  100.     args += [''.join(map(chr, b)).encode("hex")]  
  101.     args += [get_ciphertext(f, a)]  
  102.     args += [get_ciphertext(f, b)]  
  103. subkey3 = wrapper(["./a.out"] + args)  
  104. print "[+] subkey3 is %s" % `subkey3`  
  105.  
  106. print "[+] recovering subkey2..."  
  107. diff_list, args = [0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00], ["2", subkey3]  
  108. for x in xrange(NUM_CHECK):  
  109.     a, b = get_plaintext(diff_list)  
  110.     args += [''.join(map(chr, a)).encode("hex")]  
  111.     args += [''.join(map(chr, b)).encode("hex")]  
  112.     args += [get_ciphertext(f, a)]  
  113.     args += [get_ciphertext(f, b)]  
  114. subkey2 = wrapper(["./a.out"] + args)  
  115. print "[+] subkey2 is %s" % `subkey2`  
  116.  
  117. print "[+] recovering subkey1..."  
  118. diff_list, args = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04], ["1", subkey3, subkey2]  
  119. for x in xrange(NUM_CHECK):  
  120.     a, b = get_plaintext(diff_list)  
  121.     args += [''.join(map(chr, a)).encode("hex")]  
  122.     args += [''.join(map(chr, b)).encode("hex")]  
  123.     args += [get_ciphertext(f, a)]  
  124.     args += [get_ciphertext(f, b)]  
  125. subkey1 = wrapper(["./a.out"] + args)  
  126. print "[+] subkey1 is %s" % `subkey1`  
  127.  
  128. print "[+] recovering all subkeys..."  
  129. diff_list, args = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], ["0", subkey3, subkey2, subkey1]  
  130. for x in xrange(NUM_CHECK):  
  131.     a, b = get_plaintext(diff_list)  
  132.     args += [''.join(map(chr, a)).encode("hex")]  
  133.     args += [''.join(map(chr, b)).encode("hex")]  
  134.     args += [get_ciphertext(f, a)]  
  135.     args += [get_ciphertext(f, b)]  
  136. subkeys = wrapper(["./a.out"] + args)  
  137. print "[+] subkeys is %s" % `subkeys`  
  138.  
  139. subkeys = eval(subkeys)  
  140. subkeys = [convert_list(sk) for sk in subkeys]  
  141. kp1 = ''.join(map(chr, decrypt(map(ord, key_cipher[0:8]), subkeys)))  
  142. kp2 = ''.join(map(chr, decrypt(map(ord, key_cipher[8:16]), subkeys)))  
  143. print "[*] OK, all subkeys were recovered. plaintext is %s" % `kp1 + kp2`
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement