1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| from pwn import * from Crypto.Util.number import *
p=remote('spiral-baby.ctf.maplebacon.org',1337)
def rev_add_key(state,idx): for i in range(4): for j in range(4): state[i][j] = (state[i][j] - keys[idx][i][j]) % 255 return state
def rev_substitute(state): for i in range(4): for j in range(4): state[i][j] = SBOX.index(state[i][j]) return state
def rotate(state): state = spiralRight(state) return state
def spiralRight(matrix): right = [] for j in range(4): for i in range(3, -1, -1): right.append(matrix[i][j]) return bytes2matrix(right)
def spiralLeft(matrix): left = [] for j in range(3, -1, -1): for i in range(4): left.append(matrix[i][j]) return bytes2matrix(left)
def bytes2matrix(bytes): return [list(bytes[i : i + 4]) for i in range(0, len(bytes), 4)]
def matrix2bytes(matrix): return bytes(sum(matrix, []))
SBOX = [184, 79, 76, 49, 237, 28, 54, 183, 106, 24, 192, 7, 43, 111, 175, 44, 46, 199, 182, 115, 83, 227, 61, 230, 6, 57, 165, 137, 58, 14, 94, 217, 66, 120, 53, 142, 29, 150, 103, 75, 186, 39, 31, 196, 18, 207, 244, 16, 213, 243, 114, 251, 96, 4, 138, 197, 10, 176, 157, 91, 238, 155, 254, 71, 86, 37, 130, 12, 52, 162, 220, 56, 88, 188, 27, 208, 25, 51, 172, 141, 168, 253, 85, 193, 90, 35, 95, 105, 200, 127, 247, 21, 93, 67, 13, 235, 84, 190, 225, 119, 189, 81, 250, 117, 231, 50, 179, 22, 223, 26, 228, 132, 139, 166, 210, 23, 64, 108, 212, 201, 99, 218, 160, 240, 129, 224, 233, 242, 159, 47, 126, 125, 146, 229, 0, 252, 161, 98, 30, 63, 239, 164, 36, 80, 151, 245, 38, 107, 3, 65, 73, 204, 8, 205, 82, 78, 173, 112, 219, 136, 123, 149, 118, 32, 215, 163, 74, 134, 248, 68, 110, 45, 59, 145, 178, 156, 100, 177, 221, 2, 92, 20, 40, 144, 101, 140, 169, 116, 143, 202, 1, 113, 209, 104, 133, 128, 70, 89, 216, 147, 122, 131, 9, 249, 121, 109, 191, 77, 124, 246, 55, 198, 187, 185, 17, 60, 180, 203, 19, 158, 97, 206, 148, 5, 87, 170, 236, 222, 194, 15, 214, 241, 211, 234, 42, 41, 153, 62, 102, 152, 69, 181, 34, 48, 226, 11, 195, 154, 174, 167, 135, 232, 72, 171, 33]
SPIRAL = [ [1, 19, 22, 23], [166, 169, 173, 31], [149, 212, 176, 38], [134, 94, 59, 47], ]
def diff_attack(S,a,b,m): z=[] for x in range(len(S)): if (S[x]-S[(x+a)%255])%255==b: z.append((x-m)%255) return z
key=[0]*16 diff=0x34
idx=0 while True: sign=0 tmp=[] x=1 while True: se=hex(x)[2:].rjust(2,'0')*16 p.sendlineafter('>>> ','2') sleep(0.01) p.sendline(se) re=int(p.recvline()[:-1],16) cipher1=bytes2matrix(long_to_bytes(re)) for i in range(3): cipher1=rotate(cipher1) xx=(x+diff)%255 se=hex(xx)[2:].rjust(2,'0')*16 p.sendlineafter('>>> ','2') sleep(0.01) p.sendline(se) re=int(p.recvline()[:-1],16) cipher2=bytes2matrix(long_to_bytes(re)) for i in range(3): cipher2=rotate(cipher2) beta=(cipher1[idx//4][idx%4]-cipher2[idx//4][idx%4])%255 print(diff_attack(SBOX,diff,beta,x)) if sign==0: tmp.extend(diff_attack(SBOX,diff,beta,x)) sign+=1 if len(tmp)==1: key[idx]=tmp[0] idx+=1 break tmp=list(set(tmp).intersection(diff_attack(SBOX,diff,beta,x))) x+=1 if key[len(key)-1]!=0: break print(key)
key=bytes(key) keys=[bytes2matrix(key)] keys.append(spiralLeft(keys[-1])) p.sendlineafter('>>> ','1') re=p.recvline()[:-1] for i in range(0,len(re),32): tmp=int(re[i:i+32],16) c=bytes2matrix(long_to_bytes(tmp)) c=rev_add_key(c,1) for j in range(3): c=rotate(c) c=rev_substitute(c) m=rev_add_key(c,0) print(matrix2bytes(m))
|