sandwich
1 | from Crypto.Util.number import * |
部分已知信息打copper flag的长度为39,开头的‘flag{’为5字节已知,结尾‘}’1字节已知,中间33字节未知,并且pad1填充了12位,pad2填充了15位,实际上是在66位长度下打33位未知m的copper攻击
1 | from Crypto.Util.number import * |
因式分解
题目 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
28from Crypto.Util.number import *
from Crypto.Util.number import *
from gmpy2 import*
from secret import flag,a,b,c
m = bytes_to_long(flag)
p = getPrime(256)
q = getPrime(256)
n = p * q
e = 65537
_q = int(bin(q)[2:][::-1] , 2)
c = pow(m,e,n)
print('n =',n)
print('c =',c)
'''
n = 7688109450918412752403544831281002390909833419780604228031807748258766149305710928557842935597759373483911172486806200079137977020089610947423466744079981
c = 6470273779347221033316093386019083111753019159457126878637258794718443144439812725263309232245307744208957171971247518708231996986359926490571921925899978
'''
assert a**3+b**3+c**3 == 3*a*b*c
gift = secert**3 - 9*secert + 8
print(gift)
assert 3*(p ^ _q) == a + b + c
#161744543025906043015341053617192505383170887730249139858963740290526212140704080759262652291118514899026423289750859144580744539630861592469339392076429871619231819466016568833490774183803728570722246743806426891426039708100100501
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import string
from secret import hint
from secret import encrypt
import random
dicts = string.ascii_lowercase +"{=}"
key = (''.join([random.choice(dicts) for i in range(4)])) * 8
assert(len(hint) == 32)
assert(len(key) == 32)
cipher = encrypt(hint, key) #Vigenere
print(cipher)
# cp=wmaunapgimjfpopeblvup=aywqygb1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import string
import itertools
dicts = string.ascii_lowercase + "{=}"
enc = 'cp=wmaunapgimjfpopeblvup=aywqygb'
for k in itertools.product(dicts, repeat=4):
key = ''.join(k)
key=key*8
print(key)
numenc = [dicts.index(i) for i in enc]
numkey = [dicts.index(i) for i in key]
flag = ''
for i in range(len(enc)):
# assert len(numenc) == len(numkey)
ans = (numenc[i] - numkey[i % 4]) % 29
flag += dicts[ans]
if 'secret' in flag:
print(flag)
break
#tellasecret{a=secert}keepsilentt1
2
3assert a**3+b**3+c**3 == 3*a*b*c
gift = secert**3 - 9*secert + 8
print(gift)1
2
3
4
5
6
7
8
9
10
11
12gift = 16174454302590604301534105361719250538317088773024913985896374029052621214070408075926265229111851489902642328975085914458074453963086159246933939207642987161923181946601656883349077418380372857072224674380642689142603970810010050
var('t')
f = a^3 - 9*a + 8 - gift
res = solve([f],[t])
print(res)
'''
[
t == -I*sqrt(479675667122028192327307598929249450109555498652389081855962114336125186835432726261488440976511535706065147589710878075747126062261808231937972111506698) - 12644836457648476210643410284347264244894171176836870123994247554995746446663,
t == I*sqrt(479675667122028192327307598929249450109555498652389081855962114336125186835432726261488440976511535706065147589710878075747126062261808231937972111506698) - 12644836457648476210643410284347264244894171176836870123994247554995746446663,
t == 25289672915296952421286820568694528489788342353673740247988495109991492893326
]
'''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
59from Crypto.Util.number import *
import sys
sys.setrecursionlimit(1500)
pxorq = 25289672915296952421286820568694528489788342353673740247988495109991492893326
n = 7688109450918412752403544831281002390909833419780604228031807748258766149305710928557842935597759373483911172486806200079137977020089610947423466744079981
c = 6470273779347221033316093386019083111753019159457126878637258794718443144439812725263309232245307744208957171971247518708231996986359926490571921925899978
e = 65537
leak_bits = 256
pxorq = str(bin(pxorq)[2:]).zfill(leak_bits)
def find(ph,qh,pl,ql):
l = len(ph)
tmp0 = ph + (leak_bits-2*l)*"0" + pl
tmp1 = ph + (leak_bits-2*l)*"1" + pl
tmq0 = qh + (leak_bits-2*l)*"0" + ql
tmq1 = qh + (leak_bits-2*l)*"1" + ql
if(int(tmp0,2)*int(tmq0,2) > n):
return
if(int(tmp1,2)*int(tmq1,2) < n):
return
if(int(pl,2)*int(ql,2) % (2**(l-1)) != n % (2**(l-1))):
return
if(l == 128):
pp0 = int(tmp0,2)
if(n % pp0 == 0):
pf = pp0
qf = n//pp0
phi = (pf-1)*(qf-1)
d = inverse(e,phi)
m1 = pow(c,d,n)
print(long_to_bytes(m1))
exit()
else:
if(pxorq[l] == "1" and pxorq[255-l] == "1"):
find(ph+"1",qh+"0","1"+pl,"0"+ql)
find(ph+"0",qh+"0","1"+pl,"1"+ql)
find(ph+"1",qh+"1","0"+pl,"0"+ql)
find(ph+"0",qh+"1","0"+pl,"1"+ql)
elif(pxorq[l] == "1" and pxorq[255-l] == "0"):
find(ph+"1",qh+"0","0"+pl,"0"+ql)
find(ph+"0",qh+"0","0"+pl,"1"+ql)
find(ph+"1",qh+"1","1"+pl,"0"+ql)
find(ph+"0",qh+"1","1"+pl,"1"+ql)
elif(pxorq[l] == "0" and pxorq[255-l] == "1"):
find(ph+"0",qh+"0","1"+pl,"0"+ql)
find(ph+"0",qh+"1","0"+pl,"0"+ql)
find(ph+"1",qh+"0","1"+pl,"1"+ql)
find(ph+"1",qh+"1","0"+pl,"1"+ql)
elif(pxorq[l] == "0" and pxorq[255-l] == "0"):
find(ph+"0",qh+"0","0"+pl,"0"+ql)
find(ph+"1",qh+"0","0"+pl,"1"+ql)
find(ph+"0",qh+"1","1"+pl,"0"+ql)
find(ph+"1",qh+"1","1"+pl,"1"+ql)
find("1","1","1","1")
#b'flag{80a59062-9bbf-99a3-6af0-a24e94032163}'