InfantRSA | solved
给了 $p,q$ 直接由 $m\equiv c^{(p-1)(q-1)}(\mod pq)$ 得到明文
hgame{t3Xt6O0k_R5A!!!}
Affine | solved
暴力求得 $A=14,B=13$
hgame{M4th_u5Ed_iN_cRYpt0}
not_One-time | solved
又是道暴力2333
每次可以从 Oracle 得到一个 flag 每个字符异或上一个随机生成的相同长度的 key_stream, 重点在于题目保证 key_stream 的自符只包括大小写和数字。
OTP的话显然没什么好办法,只能每次得到密文后对每一位试可能的字符,如果按此假设的那一位不合法,则排除。无限获取密文,知道每一位上都只剩一种可能性为止,则得到 flag.
1 | import string |
hgame{r3us1nG+M3$5age-&&~rEduC3d_k3Y-5P4Ce}
Reorder | solved
重排加密,输入一个和 flag 一样长且每个字符不一样的字符串,从此得知重排规则,即可解密。
1 | org = "abcdefghijklmnopqrstuvwxyz123456" |
hgame{jU$t+5ImpL3_PeRmuTATi0n!!}
Verification_code | solved
暴力
1 | from hashlib import sha256 |
hgame{It3Rt0O|S+I5_u$3fu1~Fo2_6rUtE-f0Rc3}
Remainder | solved
中国剩余定理,类似 RSA ?
1 | p = 94598296305713376652540411631949434301396235111673372738276754654188267010805522542068004453137678598891335408170277601381944584279339362056579262308427544671688614923839794522671378559276784734758727213070403838632286280473450086762286706863922968723202830398266220533885129175502142533600559292388005914561 |
hgame{CrT_w0Nt+6Oth3R_mE!!!}
Inv | solved
排列换位置,看成乘法,写个逆运算即可。
(正解是扩展欧几里得?无所谓了
1 | s595 = b'\xc8&\xc1E\xbe*\xc5\x84\xdb1\x05\x9b\xc0\xf2\xac/\x0b0\x8d\'\xc2b\x89\x93\xa6\xcd\xe1\x1b\xf4H\xffa\x90A\xf7,(\xea?\xa8\xa0\x8b\xf1\xf9"X\n\x86fj\x074\x7fBO\xd4F\xbd\xe6\xd9\xa7\xaf\x8a\x8c\xde\xab;!PT\x15)+w\xbc\x00>\xc6g\xc3\x85=9K\xb6<\xb7x\xaeUG\x83vk\xa9\xf6{\x03Y\x87\x14e\xfd\xed@i\xcc.\xd1\xebo\x106\xe2\xe7\xd7\xeeu\x9e\xfe\x95^R\xfb8\x04\xb4S\x16\xe0\xad\xd8\x98n\xca\xe4\xdd\xd2\xc7\x99l\xb3\\2L\xa3\x1d:_\x12\xb87\x17\x01\xb1#~q\x1c\t\xe8\xdar\xef\xcb\x0c\xe5\x80\xdf\xc9y\x0e`\xe9\x94\xd0\xcfW\x1f5\xf5h\xbf\xba\x91\xb9d\xfcM\x81\xec\x88\xb2c\x9f\xa4J|\xd3m\xd6s\xd5\x92\x9d\x9a3\xa2\xb5\xfa\x19N\xa1\x82][\xf8\x06\x13\xdcC\x1e\x1a\xaa\xc4tz\x08\x8f%$D\xbb\x97 \xce\x96V\xe3\x02I\x18\x11\x0f\r\xf3p\x8e\xa5Z-\xf0}\xb0Q\x9c' |
hgame{U_kN0w~tH3+eXtEnD-EuC1iD34n^A1G0rIthM}
notRC4 | solved
RC4密码,给出了乱序的 Sbox ,穷举 j 还原出原先的 Sbox 即可解密。
1 | c = b'ry\x80\xe3*\xb1\x04m\r\x12R\xeaW\x80\xba\xf7\xc5\x02g8Z\xfe\xb8f\xf5\xdc\xec\xdb\xe6\xe6\xa6\xc61\x92\xeb6K\xa1"\x01A\xfbP\xf1P\xf0\x8dQ\x81~' |
hgame{Oooooo00__reVEr$e~THE~PrGa+OF+rC4++OO000O0O}
RSA? | solved
本质签到题,难度全靠骗
发现 $n$ 是质数,且 $n\equiv3(\mod4)$,直接用结论:
若 $m^2\equiv c (\mod n)$, 则 $m\equiv c^\frac{n+1}{4}(\mod n)$
想了很久 $q$ 怎么用,结果发现给出 $q$ 只是为了唬人
1 | from Crypto.Util.number import long_to_bytes |
hgame{eaa5262c-4631-46ef-a97b-53277ab7e1d8}
ToyCipher_XorShift | solved
难得拿了二血,可能大家被分值吓到了?
本质码农模拟题。XorShift密码本身就是可逆的,逆着写就好了……
1 | from Crypto.Util.number import long_to_bytes |
hgame{tHi$+4lgOr1thM_i5_3@sY-t0~b2EaK}
Exchange | solved
好恶心的题,调了一下午
数学上不难,在双方交换 $A,B$ 时向双方分别发送错误的 $A’=B’=g^2$
这样双方计算得到的 $S_a=A^2,S_b=B^2$
那么我们得知 $C_b’$ 后即可计算 $m_b\equiv C_b’B^{-2}(\mod p)$
需要注意的是Alice若收到错误的信息就不会发出 $C_a’$ 了, 因此需要将 Bob 发给她的信息改为 $C_b’’=m_bA^2\mod p$, 这样得到 $C_a$ 后即可计算 $m_a\equiv C_a’A^{-2}(\mod p)$
1 | from hashlib import sha256 |
hgame{Wow!+U_d0_tH3_m@N-1n~ThE+miDd!3_4TtAck~}
Feedback | solved
这题思维难度确实挺大的,想了一天了才恍然大悟QwQ
第一次连接服务器:由于 CFB 的特点,$K_1$ 是可以直接通过 $c_1\oplus m_1$ 得到的,这样得到 $M_1=C_1\oplus K_1$
第二次连接服务器:首先用前述方法求出此次连接的 $K_1$. 对于 $K_2$ 不同的明文得出的就不一样了,所以需要取 $c_2=\text{encrypt}(M_1)+\text{urandom(16)}$ ,这样就可以得到 $C_1$ 所对应的 $K_2=c_2[16:]\oplus m_2[16:]$, 并得到 $M_2=C_2\oplus K_2$
第三次连接服务器:同理,求出 $K3,M3$
下面贴的脚本是第三次连接服务器的脚本
1 | import os, random |
hgame{51b72d4cd23b2fe672a874cb44020868}
CBCBC | solved
分析加密流程发现:往密文上第 $i$ 个 byte 异或一个数,则解密出的明文上第 $i+32$ 个 byte 也异或上该数。用此方法可以得到一切想要的明文的密文。
Oracle 提供一个检测密文 padding 是否合法的方法,因此从后往前对每一个 byte, 猜测该 byte 的值,将该 byte 及之后的都填充成相应的 padding,如果猜对了则解密出来的明文 padding 合法,从而猜出明文的所有 byte。
1 | import os, random |
hgame{I_like_Padding_oracle_attack_6f64ab73204ff3fe89fd90a2}
ToyCipher_Linear | solved
设 $F(x)=x<<<7\oplus x<<<2$
易证 $F$ 不可逆,但注意到 $F(a\oplus b)=F(a)\oplus F(b)$
则 $c=\sigma(m)\oplus \mu(\text{key})$
那么对于相同的 key, 每一块的 $\sigma(m)\oplus c=\mu(\text{key})$ 为定值, 而 $\sigma(m)$ 即为 key 为 0 时的密文。
可以求出该定值,这样再将 flag 的密文分块异或上定值得到 key 为 0 时的密文,再调用 decrypt 函数解密即可。
1 | #!/usr/bin/env python3 |
hgame{r0TAT!on_&&-x0r 4Re-b0tH~l1neaR_0pEr4t1On5}