Wp for C1CTF2020's Crypto 先放一句话role=Tsunate;
题目倒是蛮好玩的
Base的千层套路 拿到的是一个base编码后的结果,写个脚本一直解码,最后得到flag
c1ctf{Ba5e_3nc0ding_i5_e4sy}
PigIsSoCute 题目给了一个piggggggg.txt
,打开是base64编码的一个图片,在线转换一下得到一个图片
猪圈密码解一下得到一个字符串,根据题目描述尝试栅栏后得到一个有意义的字符串
c1ctf{pigissocutebutporkissoexp}
ezrsa 刚开始看到 $e=3$ ,而且三个密文都一样,并且比 $n$ 小得多,尝试直接开三次方后无果,其实是出题人自己把数据给错了,给的c根本就不是立方,直接就是flag。
后来更新了附件, $c$ 和 $n$ 大小差不多,但是给了三次加密,拓展欧几里得合并一下就有了
MITM 刚开始出题人把题目名称写错了哈哈哈哈哈
既然是中间人攻击,那么我们就应该在与A
交互时伪装成B
,在与B
交互时伪装成A
过了pow之后给了 $g$ 和 $p$ ,这里一定要把和谁交互分清楚,因为出题人名字起的太像了,所以刚开始把自己给绕进去了,我们把与Hiro
交互的数据统一加上Hiro
前缀,把与Zero
交互的数据统一加上Zero
前缀,根据题目在[2,p-1)
随便选个数计算 $Hiro_A =g^{Hiro_a}\ mod\ q$ ,并且得到 $Zero_A$ ,然后再与Hiro
进行一次秘钥交换,得到 $Hiro_B$ 和 $ZeroB$ ,这样我们就可以得到与两个人分别的Key
,因为 $Hiro_{Key}= {Hiro_B}^{Hiro_a} = {Hiro_A}^{Hiro_b}$ ,所以再两人交换 $m$ 时就可以进行自如的加密解密,最后得到的两个 $m$ 拼起来就是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 56 57 58 59 60 61 62 63 from string import digits, ascii_lettersfrom pwn import *from hashlib import sha256from Crypto.Util.number import *table = digits+ascii_letters r = remote("8.136.142.239" , "30400" ) def passpow (): rev = r.recvuntil("sha256(XXXX+" ) suffix = r.recv(16 ).decode() r.recvuntil(" == " ) res = r.recv(64 ).decode() def f (x ): hashresult = hashlib.sha256((x+suffix).encode()).hexdigest() if hashresult == res: return 1 else : return 0 prefix = util.iters.mbruteforce(f,table,4 ,'upto' ) r.recvuntil("Give me XXXX:" ) r.sendline(str (prefix)) passpow() print ('Successfully pass the pow!' )r.recvuntil("[Hiro]: g = " ) g = int (r.recvline(False ).strip().decode()) r.recvuntil("[Hiro]: p = " ) p = int (r.recvline(False ).strip().decode()) Hiro_a = 3 Hiro_A = pow (g,Hiro_a,p) r.recvuntil("[Aside]: You intercepted Zero's message, which is `A = " ) Zero_A = int (r.recvuntil("`" )[:-1 ].strip().decode()) r.recvuntil("> " ) r.sendline(str (Hiro_A)) Zero_b = 3 Zero_B = pow (g,Zero_b,p) r.recvuntil("[Aside]: You intercepted Hiro's message, which is `B = " ) Hiro_B = int (r.recvuntil("`" )[:-1 ].strip().decode()) r.recvuntil("> " ) r.sendline(str (Zero_B)) Hiro_Key = pow (Hiro_B,Hiro_a,p) Zero_Key = pow (Zero_A,Zero_b,p) r.recvuntil("[Aside]: You intercepted Hiro's message, which is `C_b = " ) Hiro_got = int (r.recvuntil("`" )[:-1 ].strip().decode()) r.recvuntil("> " ) m = (Hiro_got * inverse(Hiro_Key,p)) % p print (long_to_bytes(m))Zero_give = (m * Zero_Key) % p r.sendline(str (Zero_give)) r.recvuntil("[Aside]: You intercepted Zero's message, which is `C_a = " ) Zero_got = int (r.recvuntil("`" )[:-1 ].strip().decode()) r.recvuntil("> " ) m = (Zero_got * inverse(Zero_Key,p)) % p print (long_to_bytes(m))Hiro_give = (m * Hiro_Key) % p r.sendline(str (Hiro_give))
c1ctf{Dif7ie_he1lman_is_n0t_p3rfect}
aesstudy1 写题解之前说点有的没的,因为出题人太爱讲故事,所以…
题目就是套娃AES,给一步做一步就好了,
step1 给了key
,给了msg
,要我们返回加密后的结果
step2 看来半天不知道要我干啥,也不知道要我返回啥,自己一个人傻看了一个小时才去问了出题人
我怎么知道要把Tsunate换成Kakashi啊
因为AES是16个字节一块块加密的,而且是ECB模式,因为出题人的精心构造,正好4块并且结构很整齐,如下:
1 2 3 4 Tsunate can see AAA Message and Kakashi can see BBB Message.....
所以,只需要把第三块的密文覆盖到第一块再打回去就行了
另外,我怎么知道要把前面那句话一起打回去啊
step2过了之后就能拿到第一个flag了
setp3 要登录,并且一共有两块,第一块会作为iv
和解密后的第二块异或,而题目告诉了我们明文第二块是MN;role=Konoha;
,给第一块异或\x00\x00\x00\x00\x00\x00\x00\x00Kakashi;
和\x00\x00\x00\x00\x00\x00\x00\x00Tsunate;
就可以使得明文变成role=Tsunate;
我怎么知道要换成Tsunate啊,不是Konoka的登录系统吗
step4 服务器提供一次AES的解密,让我们猜iv
,我们给服务器发送32位\x00
,得到两块结果,根据AES.CBC的解密,可以知道第一块是D(input1)^iv
,第二块是D(input2)^input1
,因为我们构造的input1
和input2
都是16位\x00
,所以这两块异或所得就是iv
,再发回服务器就行了
step4过掉,第二个flag就拿到了
finalexp.py 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 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("8.136.131.7" , "30339" ) r.recvuntil("The key in hex is " ) key1 = long_to_bytes(int (r.recvuntil(',' )[:-1 ].strip().decode(),16 )) r.recvuntil("the msg in hex is " ) msg1 = long_to_bytes(int (r.recvuntil(',' )[:-1 ].strip().decode(),16 )) r.recvuntil("the AES-ECB-128 encryption:" ) aes1 = AES.new(key1,AES.MODE_ECB) cipher1 = aes1.encrypt(msg1) cipher1 = hex (bytes_to_long(cipher1))[2 :] r.sendline(cipher1) r.recvuntil(".....|" ) cipher2 = r.recvline(False ) cipherlist = [] for i in range (4 ): cipherlist.append(cipher2[i*32 :(i+1 )*32 ]) payload2 = b'Kakashi can see AAA Message and Kakashi can see BBB Message.....|' +cipherlist[2 ]+cipherlist[1 ]+cipherlist[2 ]+cipherlist[3 ] r.recvuntil("Input the message after you modified:" ) r.sendline(payload2) r.recvuntil("And you interrupt the ciphertext " ) iv = long_to_bytes(int (r.recv(32 ).strip().decode(),16 )) cipher3 = r.recv(32 ) r.recvline() aaa = b' Kakashi;' bbb = b' Tsunate;' payload3 = '' for i in range (len (aaa)): tmp = aaa[i] ^ bbb[i] ^ iv[i] payload3 += chr (tmp) payload3 = payload3.encode('latin1' ) payload3 = hex (bytes_to_long(payload3))[2 :] payload3 = payload3+str (cipher3)[2 :-1 ] r.sendline(payload3) r.recvuntil('Input something:' ) r.sendline('\x00' *32 ) r.recvuntil('your input (in hex): ' ) iiv = r.recvline(False ) print (iiv)iiv1 = long_to_bytes(int (iiv[0 :32 ].strip().decode(),16 )) iiv2 = long_to_bytes(int (iiv[32 :64 ].strip().decode(),16 )) print (iiv1)print (iiv2)payload4 = '' for i in range (len (iiv1)): tmp = iiv1[i] ^ iiv2[i] payload4 += chr (tmp) payload4 = payload4.encode('latin1' ) payload4 = hex (bytes_to_long(payload4))[2 :] r.recvuntil('Tell me the iv in hex:' ) r.sendline(payload4) r.interactive()
BuyAndSell 2 PaddingOracleAttack确实很简单,但这压轴web我是一点办法都没有(
我是废物!
假装自己AK了,爬了爬了