· 7 years ago · Jul 29, 2018, 01:42 PM
1#-*- coding:utf-8 -*-
2
3from random import *
4from itertools import product
5from sock import Sock
6
7from led import *
8import led
9
10def to_state(p_data):
11 state = [[None] * 4 for _ in xrange(4)]
12 for i in range(0,16):
13 if (i%2) == 1:
14 state[i/4][i%4] = input[i>>1]&0xF
15 else:
16 state[i/4][i%4] = (input[i>>1]>>4)&0xF
17 return state
18
19def from_state(state):
20 if len(state) == 16:
21 state = [state[i:i+4] for i in xrange(0, 16, 4)]
22 output = [0]*8
23 for i in range(0,8):
24 output[i] = ((state[(2*i)/4][(2*i)%4] & 0xF) << 4) | (state[(2*i+1)/4][(2*i+1)%4] & 0xF)
25 return output
26
27# AK AC SB SR MC
28
29LOCAL_LAZY = sbox_lazy[::]
30led.sbox_lazy = range(16)
31
32# to disable shuffling
33# LOCAL_LAZY = range(16)
34
35NDATA = 5
36if 0:
37 # local oracle
38 def oracle(state, nr=1):
39 led.sbox_lazy = LOCAL_LAZY
40 p_data = from_state(state)
41 res = map(ord, Lazy_LED_enc(p_data, SECRET_KEY, 128, nr) )
42 led.sbox_lazy = range(16)
43 return res
44
45
46 SECRET_KEY = range(32, 32+16)
47 SECRET_KEY_NIBBLES = [None] * 32
48 for i in range(0, 32):
49 if (i%2) == 1: SECRET_KEY_NIBBLES[i] = SECRET_KEY[i>>1]&0xF
50 else: SECRET_KEY_NIBBLES[i] = (SECRET_KEY[i>>1]>>4)&0xF
51else:
52 # challenge oracle
53 f = Sock("crypto.task.ctf.codeblue.jp 13337")
54
55 def oracle(state, nr=1):
56 p_data = from_state(state)
57 res = "".join(map(chr, p_data))
58 f.read_until("in hex.")
59 f.send_line(res.encode("hex") + "lazy%d" % nr)
60 f.read_until("ciphertext:")
61 f.read_line()
62 c = f.read_line().strip().decode("hex")
63 return map(ord, c)
64
65keys4 = list(product(range(16), repeat=4))
66
67plain = range(16)
68c0 = oracle(plain, 1)
69groups = set()
70groupid = {}
71for i in xrange(16):
72 p = plain[::]
73 p[i] ^= 1
74 c = oracle(p, 1)
75
76 inds = tuple(j for j in xrange(16) if c[j] != c0[j])
77 print i, inds
78 groups.add(inds)
79 if inds not in groupid:
80 groupid[inds] = i
81 if len(groups) == 4:
82 break
83groups = sorted(groups)
84
85data = []
86for i in xrange(NDATA):
87 print "Data1", i
88 p = [randint(0, 15) for _ in xrange(16)]
89 c = oracle(p, 1)
90 cs = []
91 for g in groups:
92 t = tuple(sorted(c[j] for j in g))
93 cs.append(t)
94 cs = tuple(cs)
95 data.append((p, c, cs))
96
97orders = [
98[0, 5, 10, 15],
99[1, 6, 11, 12],
100[2, 7, 8, 13],
101[3, 4, 9, 14],
102]
103known_key = [0] * 32
104
105print "Brute 1"
106for ks in keys4:
107 k_data = [None] * 16
108 for ors in orders:
109 for kch, j in zip(ks, ors):
110 k_data[j] = kch
111 k_data += [None] * 16
112
113 bad = set()
114 for p, c, cs_good in data:
115 p_data = from_state(p)
116 c_data = map(ord, Lazy_LED_enc(p_data, k_data, 128, 1, keynib=k_data))
117
118 for g, t_good in zip(groups, cs_good):
119 t = tuple(sorted(c_data[groupid[g] + 4*j] for j in xrange(4)))
120 if t_good != t:
121 bad.add(g)
122 if len(bad) == 4:
123 break
124 else:
125 good = [g for g in groups if g not in bad]
126 print "found good", ks, good
127 for g in good:
128 for i, c in enumerate(ks):
129 known_key[orders[groupid[g]][i]] = c
130
131
132print "STEP 2"
133data = []
134for i in xrange(NDATA):
135 print "Data2", i
136 p = [randint(0, 15) for _ in xrange(16)]
137 c = oracle(p, 5)
138 cs = []
139 for g in groups:
140 t = tuple(sorted(c[j] for j in g))
141 cs.append(t)
142 cs = tuple(cs)
143 data.append((p, c, cs))
144
145print "Brute 2"
146for ks in keys4:
147 k_data = [None] * 16
148 for ors in orders:
149 for kch, j in zip(ks, ors):
150 k_data[j] = kch
151 k_data = known_key[:16] + k_data
152
153 bad = set()
154 for p, c, cs_good in data:
155 p_data = from_state(p)
156 c_data = map(ord, Lazy_LED_enc(p_data, k_data, 128, 5, keynib=k_data))
157
158 for g, t_good in zip(groups, cs_good):
159 t = tuple(sorted(c_data[groupid[g] + 4*j] for j in xrange(4)))
160 if t_good != t:
161 bad.add(g)
162 if len(bad) == 4:
163 break
164 else:
165 good = [g for g in groups if g not in bad]
166 print "found good", ks, good
167 for g in good:
168 for i, c in enumerate(ks):
169 known_key[16+orders[groupid[g]][i]] = c
170
171print known_key
172key = "".join("%x" % c for c in known_key)
173print key
174
175for i in xrange(200):
176 for j in xrange(10):
177 f.send_line(key)
178 print i, `f.read_one()`
179f.interact()
180# CBCTF{Th3_L4zy_Encrypt3r_mu5t_D13!!_05a3334a7fefca7c2ebaedb018da29fb}