defcompute_obfuscated_tokens(self,ti_list): Ti_list=[] c = randint(0,2**32) for i inrange(len(ti_list)): encrypted = int_to_bytes(self._encrypt(ti_list[i]).x) Ti_list.append(H2(c+i,encrypted)) return (c,Ti_list)

def_encrypt(self,msg): return (g*bytes_to_int(H1(msg))+h)*self.k_sr '''''' if i == '1': n-=1 if n < 1: exit() R = input().strip() Rinit = R.encode('utf-8') # 2lazy2compress R = R.split(' ')# 给R点 R = ECC.EccPoint(int(R[0],16),int(R[1],16)) sig = b64.b64decode(input().strip())# 对Rinit进行签名

if R == g or R == h: print("Rule entropy too small.") exit()

ifnot ver.verify(sig,Rinit): exit()

s1 = SR.compute_intermediate_rule(R) print(hex(s1.x)[2:],hex(s1.y)[2:]) elif i == '2': if n_traf: n_traf = False c,Ti=SR.compute_obfuscated_tokens(tokenize(secure_message)) print(str(c)+'|',end='') print(b64.b64encode(b''.join(Ti)).decode('utf-8'))

choice 1: to encrypt something by , but can’t be or . Also , you should sign the point.

choice 2: to encrypt secure message by compute_obfuscated_tokens

Solution:

In this task,we act as a MB. And in this paper , we can see here( 3.3 Exhaustive message search vulnerability ).

And find you can become an SR in a sense to encrypt msg without getting sk (k_SR) .

The implication is that you can do an MITM(man-in-the-middle) attack here.

That’s the 1st step what you should do.

The next step is how to decrypt this token. We can find that if the secure message never changes , we just need to get a set of data.

'''''' IP = "35.246.134.224" port = 32079 io = connect(IP, port) io.recvuntil(b"Hello MiddleBox. Here is my g and h:\r\n") data = io.recvline() data = data.decode().strip().split() g = (int(data[0], 16), int(data[1], 16)) data = io.recvline() data = data.decode().split() h = (int(data[0], 16), int(data[1], 16))

k0 = 233333

G = ECC.EccPoint(g[0], g[1]) H = ECC.EccPoint(h[0], h[1]) io.recvuntil(b"2. Get traffic\r\n") P1 = k0 * G io.sendline(b"1") io.sendline((hex(P1.x)[2:] + " " + hex(P1.y)[2:]).encode()) sig = ver.sign((hex(P1.x)[2:] + " " + hex(P1.y)[2:]).encode()) io.sendline(b64.b64encode(sig)) data = io.recvline() data = data.decode().split() kG = ECC.EccPoint(int(data[0], 16), int(data[1], 16))

io.recvuntil(b"2. Get traffic\r\n") P2 = k0 * H io.sendline(b"1") io.sendline((hex(P2.x)[2:] + " " + hex(P2.y)[2:]).encode()) sig = ver.sign((hex(P2.x)[2:] + " " + hex(P2.y)[2:]).encode()) io.sendline(b64.b64encode(sig)) data = io.recvline() data = data.decode().split() kH = ECC.EccPoint(int(data[0], 16), int(data[1], 16))

kG = pow(k0, n - 2, n) * kG kH = pow(k0, n - 2, n) * kH

io.recvuntil(b"2. Get traffic\r\n") io.sendline(b"2") data = io.recvline() data=data.decode().split('|') c=int(data[0]) T=b64.b64decode(data[1].encode()) print(c)

Then, let’s analyse the tokenize & compute_obfuscated_tokens.

We find that tokenize is so weak if you can know a block in it. and it’s expressed in paper.

The flag’s format is CTF{sha256} . So we can get half a token block. But we don’t know where the index of the flag is. It needs brute-force.( Only hexdigist(lower) * 4 * length(Ti) ).

Appendix:

This question is really interesting. Thanks to Ephvuln a lot !!!

I am honored to help him revise the blasting complexity of ASCII in the paper

About this Post

This post is written by Hao Jiang, licensed under CC BY-NC 4.0.