ACTF2023 Cypto
也是稍微花了一点时间给队里面的密码签到一下
EasyRSA
E ∗ D − k 1 ∗ n 1 = A E ∗ D − a ∗ n 2 = B E ∗ D − d ∗ n 3 = C E*D-k_1*n_1=A\\E*D-a*n_2=B\\E*D-d*n_3=C E∗D−k1∗n1=AE∗D−a∗n2=BE∗D−d∗n3=C
存在这三个等式关系,其中D,A,B,C均为小于E的较小数直接造格就好
M = Matrix(ZZ,[[e,e,e,2^767],
[n1,0,0,0],
[0,n2,0,0],
[0,0,n3,0]])
# e_*d_-k1*n1,n1
d=abs(M.LLL()[0][3]//2^767)
long_to_bytes(ZZ(pow(c,d,n1)))
#ACTF{5FFC427B-F14F-DCA0-C425-675B149890C2}ACTF{5FFC427B-F14F-DCA0-C425-675B149890C2}
MidRSA
手动测一下这里相比于上面卡了4-6bits的界,所以爆破一下高位就行
E ∗ ( h d + d 0 ) − k 1 ∗ n 1 = h a + A 0 E ∗ ( h d + d 0 ) − a ∗ n 2 = h b + B 0 E ∗ ( h d + d 0 ) − d ∗ n 3 = h c + C 0 E*(h_d+d_0)-k_1*n_1=h_a+A_0\\E*(h_d+d_0)-a*n_2=h_b+B_0\\E*(h_d+d_0)-d*n_3=h_c+C_0 E∗(hd+d0)−k1∗n1=ha+A0E∗(hd+d0)−a∗n2=hb+B0E∗(hd+d0)−d∗n3=hc+C0
for i in tqdm(range(70000,2^20)):
t1 = bin(i)[2:].zfill(21)
h = int('1'+t1[:3],2) << 0x23c
h1 = int(t1[3:9],2) << 1338
h2 = int(t1[9:15],2) << 1338
h3 = int(t1[15:21],2) << 1338
M = Matrix(QQ,[[-e,-e,-e,2^766,0,0,0,0],
[n1,0,0,0,0,0,0,0],
[0,n2,0,0,0,0,0,0],
[0,0,n3,0,0,0,0,0],
[-h*e,-h*e,-h*e,0,2^(1338),0,0,0],
[-h1,0,0,0,0,2^1338,0,0],
[0,-h2,0,0,0,0,2^1338,0],
[0,0,-h3,0,0,0,0,2^1338]])
# e_*d_-k1*n1,n1
res = M.LLL()
d = int(res[0][3]//2^766) + h
if b'ACTF' in long_to_bytes(ZZ(pow(c,d,n1))):
print(long_to_bytes(ZZ(pow(c,d,n1))))
CRCRC
以前有类似的题,这里应该就改了一下,去年的hackergame 不可加密的异世界。当时一点不会做。
在crc128中有一个初始值,经过调试可以得到头尾固定时的状态转移过程
s t a t e 1 − > s t a t e 2 − > s t a t e 3 − > s t a t e 4 state_1->state_2->state_3->state_4 state1−>state2−>state3−>state4
由1到2是前一段base64可正向推得,由4->3反推可以使用上面的re_crc128函数
def re_crc128(data, crc, poly = 0x883ddfe55bba9af41f47bd6e0b0d8f8f):
crc = crc ^ ((1 << 128) - 1)
for b in data[::-1]:
for _ in range(8):
if crc.bit_length() < 128:
crc = crc << 1
else :
crc = ((crc ^ poly) << 1) + 1
crc ^= b
return crc
所以最终要解决就是已知状态2和状态3,求一个在base64表中的的data值
c r c ( Δ ⊕ a ) ⊕ c r c ( Δ ⊕ b ) = const ∀ Δ crc(\Delta \oplus a)\oplus crc(\Delta \oplus b) = \textrm{const}\quad \forall \Delta crc(Δ⊕a)⊕crc(Δ⊕b)=const∀Δ
由这个式子可以转换成mod2加法,由于需要可见字符,所以考虑更多bytes的data,测试考虑30位的data,这样base64decode可以满足flag条件
如何对于矩阵来说
则矩阵形式为 128 × ( 30 ∗ 8 ) × X = 128 ∗ 1 128\times (30*8)\times X=128*1 128×(30∗8)×X=128∗1
所以可以固定 24 × 3 < 30 ∗ 8 − 128 24\times 3<30*8-128 24×3<30∗8−128解空间,直接固定每个字符前3位为010,在再解空间爆破。
改一下之前hacker game的脚本就好,具体矩阵推导看hacker game,这里不多写了
def crc128(data, poly=0x883ddfe55bba9af41f47bd6e0b0d8f8f):
crc = 0x9aefa6cb65b524cf97abaa31b3c757e3 #状态2通过前缀得来的,就不说了
for b in data:
crc ^^= b
for _ in range(8):
crc = (crc >> 1) ^^ (poly & -(crc & 1))
return crc ^^ ((1 << 128) - 1)
def equivalent_affine_crc(crc = crc128, crc_bits = 128, target_bytes = 30):
zero_crc = crc(target_bytes*b"\x00")
target_bits = 8 * target_bytes
v2n = lambda v: int(''.join(map(str, v)), 2)
n2v = lambda n: vector(GF(2), bin(n)[2:].zfill(crc_bits))
# n2v_t = lambda n: vector(GF(2), bin(n)[2:].zfill(target_bits))
Affine_Matrix = []
for i in range(target_bits):
v = vector(GF(2), (j == i for j in range(target_bits)))
value = crc(long_to_bytes(v2n(v),target_bytes)) ^^ zero_crc
Affine_Matrix.append(n2v(value))
Affine_Matrix=matrix(GF(2),Affine_Matrix).transpose()
for i in range(target_bytes):
v,w,k = [0]*target_bits,[0]*target_bits,[0]*target_bits
v[i*8],w[i*8+1],k[i*8+2]=1,1,1
v = vector(GF(2), v)
w = vector(GF(2), w)
k = vector(GF(2), k)
Affine_Matrix = Affine_Matrix.stack(v)
Affine_Matrix = Affine_Matrix.stack(w)
Affine_Matrix = Affine_Matrix.stack(k)
# crc affine function: crc_128(x) = M*x+ C
return Affine_Matrix, n2v(zero_crc)
def crc_128_reverse(crc_value):
M , C = equivalent_affine_crc()
# crc affine function: crc_128(x) = M*x+ C
v2n = lambda v: int(''.join(map(str, v)), 2)
n2v = lambda n: vector(GF(2), bin(n)[2:].zfill(128))
temp = n2v(crc_value)+C
temp = vector(GF(2),list(temp)+[0,1,0]*30)
print(M.ncols(),M.nrows(),len(temp))
res = M.solve_right(temp)
bas = M.right_kernel()
K = len(bas.basis())
for i in range(2<<K):
tr = res+bas[i]
s = long_to_bytes(v2n(tr))
# print(s)
if re.fullmatch(b'[A-Za-z0-9+/]*={0,2}', s):
print(s)
break
# return long_to_bytes(v2n(res))
crc_128_reverse(0x1bff942435a8f7d5b2f76fc4735f168b ^^ ((1 << 128) - 1))
#HTSUZATLBQWGHRQPUFXZVYBPLCPOMB
#得到RGVhciBndWVzdCwgd2VsY29tZSB0byBDUkNSQyBNYWdpYyBIb3VzZSwgSWYgeW91IGlucHV0IAHTSUZATLBQWGHRQPUFXZVYBPLCPOMBLCB5b3Ugd2lsbCBnZXQgMHg5YzZhMTFmYmMwZTk3YjFmZmY1ODQ0ZmE4OGIxZWUyZA==