message : Once upon a time there was a sweet little girl. Everyone who saw her liked her, but most of all her grandmother, who did not know what to give the child next. Once she gave her a little cap made of red velvet. Because it suited her so well, and she wanted to wear it all the time, she came to be known as Little Red Riding Hood. One day her mother said to her: "Come Little Red Riding Hood. Here is a piece of cake and a bottle of wine. Take them to your grandmother. She is sick and weak, and they will do her well. Mind your manners and give her my greetings. Behave yourself on the way, and do not leave the path, or you might fall down and break the glass, and then there will be nothing for your sick grandmother. Haha, Now you know what is Vigenere and here is your flag catctfClassicalCipherisFunny!
from Cryptodome.Cipher import AES import os from Cryptodome.Util.number import *
gift = 63318252562251464307452832207215838563457134165318957002450688189243132668670 c = b'\xbc\x87\xa21\x0bK\x05!\xeeHcx\xc5\x921\x01\xea\xe6\xa1\t\x1eN\x01\xe5@t\xa4Ih\xc9\x89\xa8\xa6+5\x01\xd5\r\xea\xc2\x99\xa5Fr\x8b\x04\xc3\x81'
from Crypto.Util.number import * from secret import flag
p = getPrime(256) a = getPrime(256) b = getPrime(256) E = EllipticCurve(GF(p),[a,b]) m = E.random_point() G = E.random_point() k = getPrime(16) K = k * G r = getPrime(256) c1 = m + r * K c2 = r * G c = bytes_to_long(flag) * int(m[0])
p = 87092522748098669829992285868403106182336017704139443077383531853456435622471 a = 101299657691551386965604314830539394563059305182047573016174562953680113433483 b = 103515188195423215634716325708078231771637293454864925173213911439839009583929 E = EllipticCurve(GF(p),[a,b]) c1 = E(32318985932447513653239654085604766474975548799844355660840553348774266479326 , 67713618814819066413787229141414188948309715152902332753488481625841113997553) c2 = E(10230302454001221645915592721533577303668058584124979714911091958630449119684 , 14068985325436327334711052593723601048735307838059332297359146101024917589355) c = 243352246360343414630771057155785496615231620377377147256856445931803440018017495259165864356164563380145135780231169307023180916540178875184090012260135703488882798862757944415926551
klist = [i for i inrange(2**15,2**16) if isPrime(i)] for k in klist: m = int((c1 - k*c2)[0]) if(c % m == 0): print(long_to_bytes(c//m)) break
clist = list("00011010011110001011101000100100111100110010011000100010000010000001011000010110110101111111110000111110011011100100001111010110100101110110111111101101000111101100011011110111110010100100000110100010111011001111110001101111000000110011110100101110011100001000000001011101101110010010010101100111111000111110101110001111010100000000111100100011011110000110100100100000001011001110100011100110111111000000110101001000011101111101001011011110100101111011101000101001111011000001101000001000101101000001110100101100101011010000001111000000101001110111110000010010111101111010110101101100001001010101110111101100001100010001110110100100100000101001110101111110110000011011000101001110011001110000111001100000010011001100011100110001000001111010000000001000010010110101010100011100110110000110111101010010000000110100011101001000111010111001101111011001111110100011010000010100100010000100100111000100010100000011011010100001011011010011011001110110011011101001111011000000010000011110111111110000011110010110001001101110101111111100110011001011101000011111011101100001010111000110100011110001001111010111011111111110111111010011101110101111110000011010001111010010011011111011100011101001000110111111000100100010001010100100101101000001001101110000001001111010111011111100010000101000111101110101001010110010001100001111011101010011111101100001001101001111110100011000111100111000000111110111110111101100111011011011111000111111000101001000000000010111110111000100101100010011100100111111100110000101101101110110001001101101010110110000100111100100100100100010011001010010110011101101100011100000100111110101110100100011111000010011010010110100000000000101011100100100111101010110011010101110010010011000110011111100011110100010001000111001011111011011111111100011010100011001110110111011101011011111001100110100010101010011101011111011011110111101100101010011111000110101100100001101000100001000111001010010000111001010001000110010110111100111110000111101111101001010010011011001000000100101010100000011") for i inrange(len(clist)): clist[i] = int(clist[i])
for i inrange(351): clist.insert(0,clist[100-1] ^ clist[200-1] ^ clist[300-1] ^ clist[349] ^ clist[350])
temp = clist[:351] for i inrange(len(temp)): temp[i] = str(temp[i]) print(long_to_bytes(int("".join(temp),2)))
import hashlib import os import random from secret import flag from Crypto.Util.number import *
defmyhash(m): blocks = [m[i*16:i*16+16] for i inrange(8)] temp = 0 for i inrange(8): temp += ((i%4)*bytes_to_long(blocks[i])) return hashlib.sha256(long_to_bytes(temp)).hexdigest()
deftask1(): m = os.urandom(128) print("m =",bytes_to_long(m)) fake_m = long_to_bytes(int(input("give me a valid value:"))) if(fake_m == m): print("Hacker!") exit() if(myhash(fake_m) == myhash(m)): return else: print("Try again!") exit()
deftask2(): table = "0123456789abcdef" prefix = "".join([random.choice(table) for i inrange(6)]) print(prefix) m = input("give me a valid message:") fake_prefix = str(hashlib.md5(m.encode()).hexdigest())[:6] if(fake_prefix == prefix): print("Congratulations!The flag is :",flag) else: print("Try again!")
task1() task2()
题目分为两个task,均要求给出一个指定条件的哈希碰撞,分别是:
给出一个自定义的哈希函数的碰撞
给出一个md5的前缀的碰撞
题目分析也就分两个task展开。
task1
观察自定义的哈希函数:
1 2 3 4 5 6
defmyhash(m): blocks = [m[i*16:i*16+16] for i inrange(8)] temp = 0 for i inrange(8): temp += ((i%4)*bytes_to_long(blocks[i])) return hashlib.sha256(long_to_bytes(temp)).hexdigest()
m = m = long_to_bytes(m) blocks = [m[i*16:i*16+16] for i inrange(8)] t = blocks[0] blocks[0] = blocks[4] blocks[4] = t b = b"" for i inrange(8): b += blocks[i] print(bytes_to_long(b))
forroundinrange(30): choice = input(MENU) if(choice == "1"): enckey = [random.getrandbits(3) for i inrange(30)] s = "" for i inrange(len(passwd)): s += str((int(passwd[i])+enckey[i]) % 10) print(s) elif(choice == "2"): passwd_1 = input("Give me the password :") if(passwd == passwd_1): print("You must be admin and here is your flag :") print(flag) else: print("Hacker!") break else: print("What are you doing?") break
题目会生成一个30位的由数字组成的随机passwd串,并且提供30次交互机会:
输入1,可以对这个字符串进行随机加密,并返回密文
输入2,可以检查passwd,若输入的数字串与passwd相等,则得到flag
完成本题需要捕捉到加密方式的漏洞,仔细观察加密方式:
1 2 3 4
enckey = [random.getrandbits(3) for i inrange(30)] s = "" for i inrange(len(passwd)): s += str((int(passwd[i])+enckey[i]) % 10)
from pwn import * from Crypto.Util.number import *
#context.log_level = 'debug'
for i inrange(10): try: r=remote("10.10.175.100",36337) test = [{str(i):0for i inrange(10)} for j inrange(30)]
#getmsg for i inrange(29): r.recvuntil(b'2.Submit') r.sendline(b"1") r.recvline() s = r.recvline().strip().decode() for j inrange(len(s)): test[j][str(int(s[j]))] = 1
passwd = "" for i in test: for j inrange(10): if(i[str(j)] == 0): if(j != 0): passwd += str((j + 2) % 10) else: if(i[str(9)] == 0): passwd += "1" else: passwd += "2" break
list_block = list(block) for i inrange(len(list_block)): list_block[i] = int(list_block[i]) enc_block = [0for i inrange(16)] for i inrange(len(XOR_net)): for j in XOR_net[i]: enc_block[i] ^= list_block[j] for i inrange(len(enc_block)): enc_block[i] = str(enc_block[i])
enc_block = "".join(enc_block) return enc_block
flag = flag.encode() m = bytes_to_long(flag) mbin = str(bin(m)[2:])
if(len(mbin) % 16 != 0): pad = "0"*(16-(len(mbin) % 16)) mbin = pad + mbin
cipher = "" for i inrange(len(mbin) // 16): block = mbin[16*i:16*i+16] cipher += encrypt(block)
if(xor13 == 0): for i inrange(2): plain[1] = unsurelist0[i][0] plain[3] = unsurelist0[i][1]
temp = [""for i inrange(8)] for i inrange(8): temp[i] = str(plain[i]) m = "".join(temp) if(chr(int(m,2)) in dic): print(chr(int(m,2)),end = "") else: for i inrange(2): plain[1] = unsurelist1[i][0] plain[3] = unsurelist1[i][1]
temp = [""for i inrange(8)] for i inrange(8): temp[i] = str(plain[i]) m = "".join(temp) if(chr(int(m,2)) in dic): print(chr(int(m,2)),end = "")
for i inrange(8,16): temp[i-8] = str(plain[i]) m = "".join(temp) print(chr(int(m,2)),end = "")
from Crypto.Util.number import * from gmpy2 import gcd
e = [71,73,79,83,89] c = [3584993665370794823538971526684020381334229506708133596895968409536999204984079790376149008440551028410578855094728886834755619619372578110783580710219803462890112213584230949057016656060118630104, 4989759276535357997528849922251020799165891301912783617877490602437969017607809593934852516575460413478605329176238636946693383565094312064286926114923643920846311211742857004745169805814074701829, 6642053461023663832524339460701405831900998203213451191972438266657726625218871972692446250954239707699495372072147429575168741548017508191044712022951983914898737345726236637602619748509541858367, 4193052693033474280001068591734478498106299089126282985098601018650036258306395170093507468070466042626395892208399682844273571796555401881696541571776607704920006607253483889750046907957450103890, 3947754756036180841352847778991940293340330235762075197248449949161868864279363865098593351636279205570062610031251872012378674221346372945053094003675053291245574344814943777453973251717985508145] knlist = [] for i inrange(4): knlist.append(c[i]**e[i+1] - c[i+1]**e[i])
for i inrange(3): kn = gcd(knlist[i],knlist[i+1]) n = kn
''' p = 137460191971421903248734970282666456357052936236325309267826027261381607494787596364694185586900461678150506751336121050696416964505449095599803784023985063 q = 9860721418259980339851718535071432928232322161057043402218644294712077358246223606787338321930806481006806109681825057554152150498652811208803589672460349 n = 1355456659130728552703937440927051368575216792075884459266902567401047511994291080770227026844213980786588891821312665440235699130632691677530305463565393918323447959981861748590308588816836911994225199705766424946089035985434128364857177612203476579345863459242384467183079400230542115729453173080726835766987 c = 793623164043246070506550788596269184419105110303948024833215670415616888488541554681716159677641475357836697213816252101550186962854788046446099017273353937153186950442792341410723820865012183730208352789289190229327937550770892606142831977859348889398082454412733823877464089108978899912318518292672709432297 '''
import random from Crypto.Util.number import * from sympy.ntheory.modular import crt
p = 137460191971421903248734970282666456357052936236325309267826027261381607494787596364694185586900461678150506751336121050696416964505449095599803784023985063 q = 9860721418259980339851718535071432928232322161057043402218644294712077358246223606787338321930806481006806109681825057554152150498652811208803589672460349 n = 1355456659130728552703937440927051368575216792075884459266902567401047511994291080770227026844213980786588891821312665440235699130632691677530305463565393918323447959981861748590308588816836911994225199705766424946089035985434128364857177612203476579345863459242384467183079400230542115729453173080726835766987 c = 793623164043246070506550788596269184419105110303948024833215670415616888488541554681716159677641475357836697213816252101550186962854788046446099017273353937153186950442792341410723820865012183730208352789289190229327937550770892606142831977859348889398082454412733823877464089108978899912318518292672709432297 e = 7*7*7*7*7
defonemod(e, q): p = random.randint(1, q-1) while(pow(p, (q-1)//e, q) == 1): # (r,s)=1 p = random.randint(1, q) return p
defAMM_rth(o, r, q): # r|(q-1 assert((q-1) % r == 0) p = onemod(r, q)
t = 0 s = q-1 while(s % r == 0): s = s//r t += 1 k = 1 while((s*k+1) % r != 0): k += 1 alp = (s*k+1)//r
a = pow(p, r**(t-1)*s, q) b = pow(o, r*a-1, q) c = pow(p, s, q) h = 1
for i inrange(1, t-1): d = pow(int(b), r**(t-1-i), q) if d == 1: j = 0 else: j = (-math.log(d, a)) % r b = (b*(c**(r*j))) % q h = (h*c**j) % q c = (c*r) % q result = (pow(o, alp, q)*h) return result
defALL_Solution(m, q, rt, cq, e): mp = [] for pr in rt: r = (pr*m) % q # assert(pow(r, e, q) == cq) mp.append(r) return mp
defALL_ROOT2(r, q): # use function set() and .add() ensure that the generated elements are not repeated li = set() while(len(li) < r): p = pow(random.randint(1, q-1), (q-1)//r, q) li.add(p) return li
amq = [pow(c,inverse(e,q-1),q)] cp = c % p cq = c % q
modlist = [p,q] for i in amp: for j in amq: c = [int(i),int(j)] m = crt(modlist,c)[0] temp = long_to_bytes(m>>1) if(b"catctf"in temp): print(temp) #flag = b"catctf{fa755bce-071e-4f1d-8cfa-37766c226065}"
import socketserver from Crypto.Util.number import * from random import getrandbits from Crypto.Cipher import AES from sympy import nextprime import binascii from secret import flag
deftask(self): for i inrange(40): choice = self.recv(menu) if(choice == b"1"): temp = getrandbits(16*8) key = (temp<<128)+temp iv = getrandbits(16*8) m = getrandbits(32*8) self.send(b"gift =",False) self.send(str(key^iv).encode()) c = enc(long_to_bytes(m),long_to_bytes(key),long_to_bytes(iv)) self.send(b"c =",False) self.send(str(bytes_to_long(c)).encode()) self.send(b'\n',False) elif(choice == b"2"): plist = [nextprime(getrandbits(32)) for i inrange(16)] n = 1 for i inrange(16): n *= plist[i] m = bytes_to_long(flag) e = 65537 c = pow(m,e,n) self.send(b"n =",False) self.send(str(n).encode()) self.send(b"c =",False) self.send(str(c).encode()) exit() else: self.send(b"What are u doing?") exit()
from pwn import * from Crypto.Util.number import * from randcrack import RandCrack from random import getrandbits from Crypto.Cipher import AES from sympy import nextprime
for i inrange(39): r.sendline(b'1') temp = r.recvline() temp = r.recvline() gift = int(str(r.recvline().decode().strip()[6:])) key = (gift >> 128 << 128) + (gift >> 128) iv = key ^ gift c = int(str(r.recvline().decode().strip()[3:])) m = bytes_to_long(dec(long_to_bytes(c),long_to_bytes(key),long_to_bytes(iv)))
#提交伪随机数 for j inrange(128//32): t = key&0xffffffff rc.submit(t) key=key>>32 for j inrange(128//32): t = iv&0xffffffff rc.submit(t) iv = iv>>32 for j inrange(256//32): t = m&0xffffffff rc.submit(t) m = m>>32
#第40次,预测伪随机数从而得到plist,进而解密 r.sendline(b'2') temp = r.recvline() temp = r.recvline() n = int(str(r.recvline().decode().strip()[3:])) c = int(str(r.recvline().decode().strip()[3:])) e = 65537 plist = [nextprime(rc.predict_getrandbits(512)) for i inrange(3)] phi_n = 1 for i inrange(3): phi_n *= (plist[i] - 1) d = inverse(e,phi_n) m = pow(c,d,n) print(long_to_bytes(m))
from Crypto.Util.number import * from random import randint from hashlib import sha256 from secret import flag
defgetkey(): x = bytes_to_long(flag[7:-1]) q = getPrime(160) whileTrue: t = 2*getPrime(1024-160) * q if isPrime(t+1): p = t+1 break h = randint(1, p-2) g = pow(h, (p-1)//q, p) y = pow(g, x, p) return(x,(p,q,g,y))
pri_key,pub_key = getkey() p,q,g,y = pub_key
m1 = b"I don't know much about DSA..." m2 = b"But I can learn!!!" h1 = bytes_to_long(sha256(m1).digest()) h2 = bytes_to_long(sha256(m2).digest())
deftask1(): p = getPrime(512) q = getPrime(512) n = p*q e = getPrime(48) print("Task1:") c = pow(m1,e,n) print("n =",n) print("c =",c) temp = int(input("Now you have a chance to decrypt a cipher:")) if(temp % n == c): print("Hacker!") exit() else: phi = (p-1)*(q-1) d = inverse(e,phi) temp_dec = pow(temp,d,n) print("The message is:",temp_dec)
deftask2(): p = getPrime(512) q = getPrime(512) n = p*q e = 65537 print("Task2") c = pow(m2,e,n) print("n =",n) print("c =",c) while(1): temp = int(input("Now you can decrypt any cipher but something lost:")) phi = (p-1)*(q-1) d = inverse(e,phi) temp_dec = pow(temp,d,n) print("The message is:",temp_dec & 1)
#step 2 for b inrange(2**16): h2 = pow(b,n,n) p = GCD(n,hint2-h2) if(p == 1): continue q = n//p phi = (p-1)*(q-1) d = inverse(e,phi) m = int(pow(c,d,n)) flag = long_to_bytes(m) print(flag) #flag = b"catctf{35b4488a-596a-5ff0-dbdb-e4ec8673b55e}" #hint1 = b"try to use ilgnidoaixamief(?)"