0%

2023第六届安洵杯

远看山有色,近听水无声。

010101

附件:

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
65
66
67
68
69
# -*- coding:utf-8 -*-
import os
import random
import string
import hashlib
import socketserver
from Crypto.Util.number import isPrime, long_to_bytes, getStrongPrime, bytes_to_long

flag = b"D0g3{******************************************}"

class MyServer(socketserver.BaseRequestHandler):
def proof(self):
random.seed(os.urandom(8))
random_str = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(20)])
str_sha256 = hashlib.sha256(random_str.encode()).hexdigest()
self.request.sendall(('SHA256(XXXX + %s):%s\n' % (random_str[4:], str_sha256)).encode())
self.request.sendall('Give Me XXXX:\n'.encode())
XXXX = self.request.recv(2048).strip()

if hashlib.sha256((XXXX + random_str[4:].encode())).hexdigest() != str_sha256:
return False

return True

def getPQN(self):
while True:
p = getStrongPrime(2048)
q = getStrongPrime(2048)
n = p * q
if p.bit_length() == 2048 and q.bit_length() == 2048 and n.bit_length() == 4096:
return p, q, n

def encrypt(self):
p, q, n = self.getPQN()
m = bytes_to_long(flag)
e = 0x10001
c = pow(m, e, n)
p = bin(p)[2:]
p1 = list(p[:1024])
p2 = list(p[1024:])
p1[random.choice([i for i, c in enumerate(p1) if c == '1'])] = '0'
p2[random.choice([i for i, c in enumerate(p1) if c == '0'])] = '1'
return n, ''.join(p1) + ''.join(p2), c

def handle(self):
if not self.proof():
self.request.sendall(b'Error Hash!')
return
n, p, c = self.encrypt()
self.request.sendall('Press 1 to get ciphertext\n'.encode())
number = self.request.recv(512).strip().decode()
if number == '1':
self.request.sendall((str(n) + '\n').encode())
self.request.sendall((str(p) + '\n').encode())
self.request.sendall((str(c) + '\n').encode())
else:
self.request.sendall('Incorrect input!\n'.encode())
return


class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass

if __name__ == '__main__':
sever = socketserver.ThreadingTCPServer(('0.0.0.0', 10001), MyServer)
ThreadedTCPServer.allow_reuse_address = True
ThreadedTCPServer.allow_reuse_port = True
sever.serve_forever()

考点在这几行代码里:

1
2
3
4
p1 = list(p[:1024])
p2 = list(p[1024:])
p1[random.choice([i for i, c in enumerate(p1) if c == '1'])] = '0'
p2[random.choice([i for i, c in enumerate(p1) if c == '0'])] = '1'

p1 中随机选择一个值为 1 的元素并将其替换为 0

p2 中由于它enumerate() 的是 p1 ,所以不确定p2 中该索引位置是 0还是1 ,即 p2 存在两种状态,可能变,也可能不变

exp:

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
import libnum
from Crypto.Util.number import *
from tqdm import *

n = 603929041261800903893255846837373435975689488156082111538579411971234122241475748036901372456410420191268918203740933624479627880138860787078343962957545877493495346831028915623609911739520855865598159115403599691845611787894864022849387193442196306247844978619825889396851220746270712372629345235420222076680115154790661980407543403831934888441296510749707016149742835334975569330963811702631399381154725473397239011407333239568323785920549918563058163802790187563167758518996273164519358725587751057556099683209931508156206102023550113078755175573231054144175740037978473444981801474458374782704295305402882601070280107624282520071733642472567932754610400320318631599250987727798785732693028629127928075161764000633755172649305820758541646921112640799416373141028867694424520169726284794592230472739528017824591893518858631575238481300188255385565135530781399021638113121796002810581237621059229401475373166398218013467690838657741784353265467188916419980824688886467277205321029087429010136873982224751707535560753990915173665180626848355707628545030678081326994468311753531184000767912265077615115921131730201921373353972239662406236256449307913217499123008959838210605102941439012579314919044679872148810171587616630982300997769
p = "11010001001011001110010111110000100100111111011100110000001011110010001010111010001000110011110011100101101111000010000110010011010001100111010001101101010110110000001000111101001111001111100111010001110001110000011101110111100010100110111111010101101000100101011101111100100100011101001001010101010100100100010111001101101001001101010111101001101010111111111010101111000110010011001001010010101110010110111110111001011011000111101110100100001100100111101100010100100000111001111111111000101001101111111001010000111110000110111110110101101001111010010001111111010011101111111011101000011101100010000000101000010010001100101001001100000000110111110101001101001010110111011100101001111111111110010100101101001110000000100011000001011110110101110111010001101000000101111101011010010000000110100011110101000000110011100001001010000111110101111011001110001000101010010110100010010000011010000000010110010110110010100000010111100011000101001110100100001110011010101011010111101000100010001000100100001110001100000011001000000011010110000100011000010010011100101101000001011110011010111111011001001101000101010011001010100000101011011010001101000110100001010111000111011111000111000110010111011111001001000111101101111101101100110000010001010100000000010111001011010110101000110010010100000110010001010001010111110010001110100100001110110100011100110010101101010010000110010000000000001101001001111000001001110111100101011010000101000001101100000011010110110001001100001010110010111110000100010010001111000111110111001110111010000010110111101110010011101010001101000100011111100111101110100100001001010110000110011110011000110010000111111110011100001110011010010010001011000011101000001100100110101001010110101000100010110000111001100011101000110010101101110000001110101010010100011111000011011010110001111000001000111011110111000111111011011101101011011011010101010001001000001001101111101101011010000001111001101010000100100011011010011011011011110011101001110011000101101010001000111100101010111001110100001001011101000111110110111111101001100110111011"
c = 86686439679874830246557653015232666024548117379353423678475364097072178826632356840355752060131181776717167764598857424931346233132869924918276685776350661070390576961130941951957979601769745016239304945501929062576701514720613007436301407348380329606694430576562909174904437860869521166636000289719433717305895080524202468368216882473127238573270504191177749274378107593390170231953722023523109786520395037511557586384515517033167064188185912051635528465308305202059386081496894767608262032863369259646855260874931901314784267182224186084544278686060811418808427473393401031779270067234650782676467179083936163361798893672177127354928129838729299397848748974202105320442165321749085841967661828478087899131573349766763269557239693467725757622240790567302886026262903788677893782986023554124746338684896334712802104286022426080359219997110717128626202867661389035295735029082783484639744693093659639224377233571685420055087016612362091684619532730540899821020173872616220719344374207934384262583860759996308412468708264575433904901696415884548016664119511545715549106666120050640487895135909555493016879887730329494392167451911914419832673885582817232756022767909864103483310200762274943174788555599167912909253375001595679099288103
e = 65537

p1 = list(p[:1024])
p2 = list(p[1024:])

a = [i for i, c in enumerate(p1) if c == '0']
b = [i for i, c in enumerate(p2) if c == '1']

for i in tqdm(a):
pp1 = list(p[:1024])
pp1[i] = '1'
pp = int((''.join(pp1)+''.join(p2)),2)
if isPrime(pp):
q = n//pp
d = libnum.invmod(e,(pp-1)*(q-1))
m = libnum.n2s(pow(c,d,n))
if b'D0g3' in m:
print(m)
break

# D0g3{sYuWzkFk12A1gcWxG9pymFcjJL7CqN4Cq8PAIACObJ}

POA

附件

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# -*- coding:utf-8 -*-
from Crypto.Util.number import isPrime, long_to_bytes, getStrongPrime, bytes_to_long
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import os
import binascii
import random
import string
import hashlib
import socketserver

FLAG = '**********'
KEY = b'****************'
IV = b'****************'


def cbc_decrypt(c, iv):
aes = AES.new(KEY, AES.MODE_CBC, iv=iv)
return aes.decrypt(c)


def encrypt():
plain_text = ''.join([random.choice(string.ascii_letters) for _ in range(2)]) + FLAG
aes = AES.new(KEY, AES.MODE_CBC, iv=IV)
plain_text = pad(plain_text.encode(), AES.block_size)
cipher = aes.encrypt(plain_text)
return IV.hex() + cipher.hex()


def asserts(pt: bytes):
num = pt[-1]
if len(pt) == 16:
result = pt[::-1]
count = 0
for i in result:
if i == num:
count += 1
else:
break
if count == num:
return True
else:
return False
else:
return False


def decrypt(c):
iv = c[:32]
cipher = c[32:]
plain_text = cbc_decrypt(binascii.unhexlify(cipher), binascii.unhexlify(iv))
if asserts(plain_text):
return True
else:
return False


class MyServer(socketserver.BaseRequestHandler):
def proof(self):
random.seed(os.urandom(8))
random_str = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(20)])
str_sha256 = hashlib.sha256(random_str.encode()).hexdigest()
self.request.sendall(('SHA256(XXXX + %s):%s\n' % (random_str[4:], str_sha256)).encode())
self.request.sendall('Give Me XXXX:\n'.encode())
XXXX = self.request.recv(2048).strip()

if hashlib.sha256((XXXX + random_str[4:].encode())).hexdigest() != str_sha256:
return False

return True

def handle(self):
if not self.proof():
self.request.sendall(b'Error Hash!')
return
cipher = encrypt()
self.request.sendall('Welcome to AES System, please choose the following options:\n1. encrypt the flag\n2. decrypt the flag\n'.encode())
n = 0
while n < 65536:
options = self.request.recv(512).strip().decode()
if options == '1':
self.request.sendall(('This is your flag: %s\n' % cipher).encode())
elif options == '2':
self.request.sendall('Please enter ciphertext:\n'.encode())
recv_cipher = self.request.recv(512).strip().decode()
if decrypt(recv_cipher):
self.request.sendall('True\n'.encode())
else:
self.request.sendall('False\n'.encode())
else:
self.request.sendall('Input wrong! Please re-enter\n'.encode())
n += 1
return


class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass

if __name__ == '__main__':
sever = socketserver.ThreadingTCPServer(('0.0.0.0', 10010), MyServer)
ThreadedTCPServer.allow_reuse_address = True
ThreadedTCPServer.allow_reuse_port = True
sever.serve_forever()

填充预言机攻击是一种针对加密数据的攻击,能让攻击者在不知道密钥的情况下解密数据的内容。

具体分析移步 CBC&Padding Oracle Attack | W’Blog (wbuildings.github.io)

exp:

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
from hashlib import sha256
import itertools
import socket
import string
from Crypto.Util.number import long_to_bytes, bytes_to_long


def proof(broke, Hash):
assert len(broke) == 16 and len(Hash) == 64
shaTable = string.ascii_letters + string.digits
for ii in itertools.permutations(shaTable, 4):
x = ''.join(ii)
s = x + broke
if sha256(s.encode()).hexdigest() == Hash:
print(x)
return x


def con():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('124.71.177.14', 10010))
proof_data = sock.recv(2048)
send_proof = (proof(proof_data[14:30].decode(), proof_data[32:96].decode())).encode()
sock.recv(2048)
sock.send(send_proof)
data1 = sock.recv(2048)
print(data1.decode())
sock.send('1\n'.encode())
cipher = sock.recv(4096).decode().split(' ')[-1]
print(cipher)
guess_iv = [0 for _ in range(16)]
restore_midd = [0 for _ in range(16)]
index = 1

for i in range(15, -1, -1):
for j in range(0, 256):
sock.send('2'.encode())
txt = sock.recv(4096).decode()
guess_iv[i] = j
mess = bytes(guess_iv).hex() + cipher[32:]
sock.send(('%s\n' % mess).encode())
result = sock.recv(4096).strip().decode()
if result == 'True':
print('find')
restore_midd[i] = index ^ j
for k in range(15, i - 1, -1):
guess_iv[k] = restore_midd[k] ^ (index + 1)
break
index += 1

m = bytes_to_long(bytes(restore_midd)) ^ int(cipher[:32], 16)
print(long_to_bytes(m))


if __name__ == '__main__':
con()

Rabin

附件

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# -*- coding:utf-8 -*-
import os
import random
import string
import hashlib
import socketserver
from secret import *
import uuid
import gmpy2
from Crypto.Util.number import isPrime, long_to_bytes, getStrongPrime, bytes_to_long


def get_flag(head):
table = string.printable
name = ''.join([random.choice(table) for i in range(10)])
return head + '{' + str(uuid.uuid5(uuid.NAMESPACE_OID, name)) + '}'


def relation():
a, b = 0, 0
for i in range(x - (2**2 - 1)):
a += pow(e1, i)
for j in range(3):
b += pow(e2, j)
if a == b:
return True
return False


def get_pqr():
while True:
p = getStrongPrime(1024)
q = getStrongPrime(1024)
if p % 4 == 3 and q % 4 == 3:
break
r = 2
while True:
r = r * x
if r.bit_length() > 1024 and isPrime(r - 1):
r = r - 1
break
return p, q, r


def encrypt():
if relation():
print('success')
else:
print('false')

flag = get_flag('D0g3')

m1 = ''.join([random.choice(string.ascii_letters) for _ in range(234)]) + ' ' + flag[:21]
m2 = flag[21:] + ' ' + ''.join([random.choice(string.ascii_letters) for _ in range(234)])

p, q, r = get_pqr()
phi = (p - 1) * (q - 1) * (q - 1)
while True:
try:
d = gmpy2.invert(e2, phi)
break
except Exception as e:
p, q, r = get_pqr()

n = p * q * r
inv_p = gmpy2.invert(p, q)
inv_q = gmpy2.invert(q, p)

c1 = pow(bytes_to_long(m1.encode()), e1, n)
c2 = pow(bytes_to_long(m2.encode()), e2, n)

return n, inv_p, inv_q, c1, c2


class MyServer(socketserver.BaseRequestHandler):
def proof(self):
random.seed(os.urandom(8))
random_str = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(20)])
str_sha256 = hashlib.sha256(random_str.encode()).hexdigest()
self.request.sendall(('SHA256(XXXX + %s):%s\n' % (random_str[4:], str_sha256)).encode())
self.request.sendall('Give Me XXXX:\n'.encode())
XXXX = self.request.recv(2048).strip()

if hashlib.sha256((XXXX + random_str[4:].encode())).hexdigest() != str_sha256:
return False

return True

def handle(self):
if not self.proof():
self.request.sendall(b'Error Hash!')
return

n, inv_p, inv_q, c1, c2 = encrypt()
self.request.sendall('Press 1 to get ciphertext\n'.encode())
number = self.request.recv(512).strip().decode()
if number == '1':
self.request.sendall(("n = %d\n" % n).encode())
self.request.sendall(("inv_p = %d\n" % inv_p).encode())
self.request.sendall(("inv_q = %d\n" % inv_q).encode())
self.request.sendall(("c1 = %d\n" % c1).encode())
self.request.sendall(("c2 = %d\n" % c2).encode())
else:
self.request.sendall('Incorrect input!\n'.encode())
return


class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass

if __name__ == '__main__':
sever = socketserver.ThreadingTCPServer(('0.0.0.0', 10100), MyServer)
ThreadedTCPServer.allow_reuse_address = True
ThreadedTCPServer.allow_reuse_port = True
sever.serve_forever()

因为是rabin,所以应该有个e=2,观察relation()方法,e1 应该比较小,猜测e1=2

e2、x简单点就是爆破,不必要花时间推

test

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
def relation():
a, b = 0, 0
for i in range(x - (2 ** 2 - 1)):
a += pow(e1, i)
for j in range(3):
b += pow(e2, j)
if a == b:
return True
return False

e1 =2

for i in range(100):
x = i
for j in range(100):
e2 = j
if relation():
print(x)
print(e2)
print()

# 4
# 0
#
# 5
# 1
#
# 6
# 2
#
# 8
# 5
#
# 16
# 90

最有可能x=6,e2=5 (试下便知)

1
2
inv_p = gmpy2.invert(p, q)
inv_q = gmpy2.invert(q, p)

$p*ip\equiv 1 \bmod q=1+k_1q$

$q*iq\equiv 1 \bmod p=1+k_2p$

两式相乘得

image-20240302122028573

两边同除以pq,得 $ip*iq=k_1k_2+\frac{k_1}{p}+\frac{k_2}{q}+\frac{1}{pq}$

根据p、q、k1、k2的 相对大小 ,$\frac{1}{pq}无限接近于0,\frac{k_1}{p}<1,\frac{k_2}{q}<1$

所以,大约 $ip*iq=k_1k_2+1$

令 $\alpha=k_1q,\beta=k_2p$

image-20240302000910531

$\alpha\beta=k_1k_2pq$

pq = n//r 是已知的,所以$\alpha+\beta,\alpha\beta$ 是已知的,构造如下一元二次方程,在用求根公式

$(x-\alpha)(x-\beta)=x^2-(\alpha+\beta)x+\alpha\beta$

$\Delta = (\alpha+\beta)^2-4\alpha\beta$

$x=\frac{(\alpha+\beta)\pm\sqrt{\Delta}}{2}$

求出k1、k2 ,再分别和 n gcd 即可得到 p、q

也可以解方程,最前面两式相加

image-20240302000833039

exp:

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
65
66
67
68
69
70
71
72
from sympy import *
import libnum
from Crypto.Util.number import *


n = 305742085102073958685058774990374612856503657611159209468741748564654591176180299818778135460948807176614281796016904753313757927457094861196369069821421681665875176139845644195736238144691839008758614457979812997005126606399842320648487994406393728514493129219688752202978501994811535834779889459729683428077498441713132964635907469366512175886337946124631196824508247375645971308484279007920881639616776491331812849657775358960227848680733861313065565269244274482334952541032707333167429562469558762781469669359057084779217532331399410333624558772093729396962312936037020992117478202860898927073068360026814644581294222733341428537874383052653054496502673372786144676806905626251642090622209277799682962538245425774337944285158783294880516595307576719556933669812074808919685419881388267486868941401975800053647291641426673593791774634377598637815942343627245274057532320854646240153245893536480745586533270387549779636700040935751519181245119278044454115223974366280075995685049945977835434961621019
inv_p = 80275679918090105134294823865673211657060049627413874971428297415355157707252877991145232186659935067961745973100698632943949790304190096567884607037119257848837354982500048978070619820510408650386626542338056277335180497955588848138448991963800265073331348097617541306117998857780109771194563339021595188562
inv_q = 91430270065720942392278749444269989843094838912787188266496611817766528132774187319335115624057615900976202412507879118712912101862728738204907877396022887953429108729897171677408597080700062032905675017013140349657979587207083820584906055634857776106802178757131724480934751871117394549988315719808677297400
c1 = 27982926262483311148784661440434049509041271145373939684263123722309350890886129800416935949757799004078048732281935770255739076672223113235604245680214981770721357810264502828783436566049916012826991722307971435988653591370445652627932863934280322586450541943726361669705223005256707033393323681199742226865639061796493744221386650671921408599281675072195109604944995246990117259752921959078570716019348911611821807743542202606017861680093899453962535751057029803212313708486252499961531916769339026243456254415795474566725045397580987945276292940425615563426872706612654673760957132954706561315315926583847756728581334589763622690426645925379033552965887091774261328484101677385760510308565939450969280431514193153901465147874994288888863961626533437546523090704677258271361008899424058968841403657808839941136606557821902221756903088734659178298942185013814206583151273573533540756898457572685280130826705824899847574123392575025182545331871707478881582060832153045557952057641871852784168481101647
c2 = 161619014853290061321220693856242384241899565606310997462914314289208211523608827698222734190386889612098570760765052452215805711014546122099647560430788381292730765852839847593053599250289125651012417026034998933486356540308165710913202176920168248765753912975464775516099366852853130484143941438754410599163284892652060800647319146257668079858962426955881454668916171211181142453679621166656675384626603665740562005722087726838877971126595828345860415781411146330129891129797182526922825440860137352029911523070206447988669663751215339049795213569586767141039747546364893768334626213397240105328357731197925663794385770706516043309955122745946633182399168534133436912290389494270925639788309351783493083085094045092781888997140679841389857851588928742292158429434570541383701331355804702559218884246423448924119442796513423570240629502315241227996438176424546368309332048747610392861954126660466095971227213870875955019656804172566974654412258429352773642042554134725696296293760333163865827998422748
ip = 80275679918090105134294823865673211657060049627413874971428297415355157707252877991145232186659935067961745973100698632943949790304190096567884607037119257848837354982500048978070619820510408650386626542338056277335180497955588848138448991963800265073331348097617541306117998857780109771194563339021595188562
iq = 91430270065720942392278749444269989843094838912787188266496611817766528132774187319335115624057615900976202412507879118712912101862728738204907877396022887953429108729897171677408597080700062032905675017013140349657979587207083820584906055634857776106802178757131724480934751871117394549988315719808677297400

x = 8
e2 = 5
def getr():
r = 2
while True:
r = r * x
if r.bit_length() > 1024 and isPrime(r - 1):
r = r - 1
break
return r
r = getr()
print('r=',r)
pq = n // r

def get_p_q():

k1k2 = inv_p*inv_q - 1
alpha_beta = pq-1
alphabeta =k1k2*pq
Detla = (alpha_beta)**2 -4*alphabeta
x1 = ((alpha_beta)+libnum.nroot(Detla,2))//2
x2 = ((alpha_beta)-libnum.nroot(Detla,2))//2
p = libnum.gcd(x1,pq)
q = libnum.gcd(x2,pq)
return p,q
# p, q = symbols("p q")
# eq1 = ip * p + iq * q - pq - 1
# eq2 = p * q- pq
# sol = solve([eq1, eq2], [p, q])
# return sol

p,q = get_p_q()
# p,q = get_p_q()[0]

def solve_rabin(c,p,q,n):
inv_p = libnum.invmod(p, q)
inv_q = libnum.invmod(q, p)
mp = pow(Integer(c), (p + 1) // 4, p)
mq = pow(Integer(c), (q + 1) // 4, q)
a = (inv_p * p * mq + inv_q * q * mp) % n
b = n - int(a)
c = (inv_p * p * mq - inv_q * q * mp) % n
d = n - int(c)
aa = [a, b, c, d]
print(aa)
for i in aa:
flag = long_to_bytes(int(i))
if b"D0g3" in flag:
print(flag)
break

solve_rabin(c1,p,q,pq)

phi = (p-1)*(q-1)*(r-1)
d = libnum.invmod(e2,phi)
m = pow(c2,int(d),n)
print(long_to_bytes(m))

# D0g3{82309bce-9db6-5340-a9e4-a67a9ba15345}

Cyber Grabs CTF 0x03 – Unbr34k4bl3 (sekai.team)

-------------    本文结束  感谢阅读    -------------