能力值:
(RANK:350 )
|
-
-
2 楼
已联系作者更改题目了。你这边,先提交第一个,即 ef589f333382266883b13d8df4c6c4c2a786c2e7d9538e4a3d98e7b6cfcddce1
4.2.5 多解罚分 = 此题难度分 × 多解罚分系数(20% )。如果防守题被发现多解,则给防守方1次修改机会,并扣多解罚分。若修改后又多解,则下线退赛,攻击方在此题获得的成绩保留不受影响。
|
能力值:
( LV12,RANK:831 )
|
-
-
3 楼
a这个程序的逻辑比较简单易懂。验证逻辑大致如下:
- 用户名长度在 [4, 20] 之间。
- 序列号长度为 64,为 hex 编码过的 32 字节。
- 0x401190 处的函数计算了用户名的 hash,不用看,直接输入 KCTF 跟到这里抠出结果即可。
- 跟 SN 有关的是验证
H(username) = RSA_PKCS1_5_unsign(AES_Decrypt(sn, key), e, n) 。 其中 AES 的 key 是硬编码的,直接提取出来即可。e = 65537,n 只有 256bit,可以直接丢进 yafu 分解。
多解的地方有两处:
- 没有限定 padding 里随机的部分可以填什么。
- hex decode 的时候对大小写一视同仁。
sfrom Crypto.Cipher import AES
import gmpy
AES_KEY = bytes.fromhex("480B62C3ACD6C8A36B18D9E906CD90D2")
n = 0x69823028577465AB3991DF045146F91D556DEE8870845D8EE1CD3CF77E4A0C39
p = 201522792635114097998567775554303915819
q = 236811285547763449711675622888914229291
assert p * q == n
phi = (p-1)*(q-1)
d = gmpy.invert(65537, phi)
for i in range(256):
data = bytes.fromhex('14AF58AD4D76D59D8D2171FFB4CA2231')
assert len(data) == 16
data = b"\x00\x02" + bytes([i]) * 13 + b"\x00" + data
assert len(data) == 32
c = int.from_bytes(data, byteorder='big')
m = pow(c, d, n)
mt = int(m).to_bytes(32, 'big')
print(AES.new(AES_KEY).encrypt(mt).hex())
|
|
|