Wp for SWPUTF2020's Crypto 很无语,T1刚开始数据给错,T2T3连不上,活活让人等到中午才更新
Happy 基础RSA,题目给出 $q+q\cdot p^3$ 和 $q\cdot p+q\cdot p^2$
我们简记为 $data_1$ 与 $data_2$ ,那么显然有 $data_1=q\cdot(p^3+1)$ 、 $data_2=q\cdot(p^2+p)$ 、 $data_1+3\cdot data_2=q\cdot(p^3+3p^2+3p+1)=q\cdot(p+1)^3$ 且 $gcd(data_1,data_2)=q\cdot(p+1)$ ,那么显然可得 $p=\sqrt{ \frac{data_1+3\cdot dota_2}{gcd(data_1,data_2)}}-1$ ,随后可得 $q=\frac{data_1}{p^3+1}$
然后RSA相关的数据都有了,直接解密即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from Crypto.Util.number import *from gmpy2 import *c = 0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9e e = 0x872a335 data1 = 1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586 data2 = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594 qp1 = gcd(data1,data2) qwq = data1 + 3 *data2 p12 = qwq // qp1 p = iroot(p12,2 )[0 ] - 1 q = data1 // (p**3 + 1 ) n = p * q phi = (p-1 ) * (q-1 ) d = inverse(e,phi) m = pow (c,d,n) print (long_to_bytes(m))
flag{happy_rsa_1}
Yusa的密码学课堂_CBC第一课 服务器提供了加密和解密,加密时会把iv
给我们,并且要使得解密后的明文为yusayusayusayusaadmin
我们记第一块区域yusayusayusayusa
记为pre
块,第二块为name
块,我们需要在保证pre
块不变的情况下改变name
块,由于是CBC模式,所以payload
需要从后往前构造
首先使用11111
进行注册,给pre
块异或11111
和admin
得到new_pre
后即可达到将name
变为admin
的目的,但是这样会使得D(new_pre)
块不可控,所以我们重新构造一个new_iv
(比如1111111111111111
),得到的结果即为D(new_pre)^new_iv
,所以我们即可构造fianl_iv
为yusayusayusayusa
异或D(new_pre)
,最终得到payload=final_iv+new_pre+name
,将其打回服务器即可
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 from string import digits, ascii_lettersfrom pwn import *from hashlib import sha256from Crypto.Util.number import *from Crypto.Cipher import AEStable = digits+ascii_letters r = remote("das.wetolink.com" , "42888" ) r.recvuntil('3. exit' ) r.sendline('1' ) r.recvuntil("What's your name?" ) r.sendline('11111' ) r.recvuntil('Here is your token(in hex): ' ) iv = long_to_bytes(int (r.recv(32 ).strip().decode(),16 )) pre = long_to_bytes(int (r.recv(32 ).strip().decode(),16 )) name = long_to_bytes(int (r.recv(32 ).strip().decode(),16 )) string1 = b'admin ' string2 = b'11111 ' new_pre = '' for i in range (16 ): x = pre[i] ^ string1[i] ^ string2[i] new_pre += chr (x) new_pre = new_pre.encode('latin1' ) new_iv = b'1' *16 payload = new_iv+new_pre+name payload = hex (bytes_to_long(payload))[2 :] r.recvuntil('3. exit' ) r.sendline('2' ) r.recvuntil('Your token(in hex): ' ) r.sendline(payload) r.recv(32 ) res = long_to_bytes(int (r.recv(32 ).strip().decode(),16 )) qwq = b'yusa' *4 finalpayload = '' for i in range (16 ): x = qwq[i] ^ res[i] ^ new_iv[i] finalpayload += chr (x) finalpayload = finalpayload.encode('latin1' ) finalpayload = finalpayload+new_pre+name finalpayload = hex (bytes_to_long(finalpayload))[2 :] print (finalpayload)r.recvuntil('3. exit' ) r.sendline('2' ) r.recvuntil('Your token(in hex): ' ) r.sendline(finalpayload) r.interactive()
Yusa的密码学课堂_ECB Key
固定,服务器提供输入一个字符串并将flag加在后面加密返回
我们先提交a
、aa
、aaa
……通过观察返回加密结果的长度可以测得flag的长度(即构建padding
)
因为是ECB,没有iv
混淆情况下,如果明文一致,密文一定是一致的,所以我们可以通过将flag一位一位推至下一个加密块,并且构建一个新块来进行爆破,找到一位即可加入已知flag来进行下一次爆破
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 from pwn import *from hashlib import sha256from Crypto.Util.number import *from Crypto.Cipher import AESBLOCKSIZE = 16 def pad (data ): pad_len = BLOCKSIZE - (len (data) % BLOCKSIZE) if len (data) % BLOCKSIZE != 0 else 0 return data + chr (pad_len) * pad_len table = '1234567890qwertyuiopasdfghjklzxcvbnm{}' r = remote("das.wetolink.com" , "42887" ) cnt = 0 def talk (x ): r.recvuntil('Amazing function: ' ) r.sendline(x) res = r.recvline(False ) return res.strip().decode() def get (x ): x = hex (bytes_to_long(x.encode('latin1' )))[2 :] return talk(x) def put (x ): s = 'b' * x return s flaghash = talk('' ) while (True ): cnt += 1 payload = '00' *cnt tmp = talk(payload) if (len (tmp) != len (flaghash)): cnt -= 1 break flaglen = len (flaghash) // 32 * 16 - cnt need = 'a' *cnt mine = '' now = 1 for i in table: tmp = pad(i + mine[:16 ]) if (len (tmp)!=16 ): tmp += ' ' * (16 - len (tmp)) payload = tmp + need + put(now) res = get(payload) if (res[:32 ] == res[-32 *(1 +now//32 ):-32 *(now//32 )]): mine = i + mine print (mine) now += 1 break
flag{7241502d1f614bf28bbaa4e898e9893e}
AK啦!溜~