[TOC]

web

signphp-ucsc

签到题,直接开启环境,然后直接找到flag文件,拿到flag

ezLaravel-ucsc

开启环境,然后直接目录扫描,看到flag.php

访问该文件,拿到flag

(这道题是出题人权限访问没控制好,导致直接扫描目录就能访问/flag.php文件。由于赛后环境无法开启,所以无法再复现了)

upload2

打开网站,看到是文件上传页面,先查看源码,发现是白名单过滤,只允许上传图片文件。

先将一句话木马改成.jpg,上传抓包修改后缀,发现响应包提示图片格式错误。

然后修改一句话木马文件,加上图片前缀(GIF89a),再次上传,显示上传give_me_flag.php。

根据提示,猜测是后端匹配了文件名,需要修改上传文件的文件名。

修改后再次上传,返回提示:文件里面需要givemeflag的内容。

于是使用记事本编辑,加上该内容,然后继续上传得到flag

image-20250420114434332

image-20250420114454859

flag{789d153e-189b-408f-93e4-a1ae286bef3c}

文件内容:

image-20250420114538326

easyphp

打开界面,直接f12查看网络包,找到一个flag的头部,是个base64编码,解码得到flag。

headache

打开界面

image-20250420114740684

根据描述,flag在响应包的header里,抓包,看到一串base64代码,解密都得到flag

Misc

本次校内赛道只有一个misc题目,但是文件里面却有三个misc文件,也就是三个misc题目随便找一个flag提交就可以了(难度大大减小)。

这里我说下三道题的思路。

three

下载附件,有三个part文件和一个流量包,先看第一个

image-20250420110707945

明显盲水印,提取盲水印,得到part1: 8f02d3e7

image-20250420110735826

然后看第二部分,二进制解码得到part2: -CE89-4D6B-830E-

image-20250420110814325

然后看第三部分,是个压缩包,需要密码。

密码应该在流量包里面,进行流量分析,看到一堆密码本

image-20250420110953826

挨个试试,然后发现密码是thinkbell

解压拿到part3: 5d0cb5695077

将上述part合在一起得到:

flag{8f02d3e7-CE89-4D6B-830E-5d0cb5695077}

提交发现错误,然后观察flag,发现第一、三部分都是小写,于是将第二部分改写成小写:

flag{8f02d3e7-ce89-4d6b-830e-5d0cb5695077}

提交成功。

小套不是套

附件里有个二维码和两个压缩包,其中两个压缩包都需要密码。

image-20250420221523561

先扫描一下二维码

image-20250420221429963

拿到密码:PassW0rd is !@#QWE123987

解压第一个压缩包,得到内层压缩包。将其放进010editor查看,发现是伪加密,于是修改回来,解压得到一张jpg图片

image-20250420221736646

image-20250420221750554

然后放进010editor,查看一下

image-20250420222749709

找到一个位置单元数据,且有IHDR数据,说明这是一个png文件的一部分数据。

将这部分提取出来,然后加上png文件头部(89 50 4E 47 0D 0A 1A 0A),得到一个png文件、

image-20250420225343244

进行各种png文件分析也没什么头绪,于是看最后一个压缩包。

发现压缩包内的文件大小都一样,于是想到CRC32爆破

image-20250420225624441

爆破出来得到一个base64编码:

1
2
3
R1JWVENaUllJVkNXMjZDQ0pKV1VNWTNIT1YzVTROVEdLVjJGTVYyWU5NNFdRTTNWR0ZCVVdNS1hNSkZXQ00zRklaNUVRUVRCR0pVVlVUS0VQQktHMlozWQ==
解码:
Key is SecretIsY0u

现在知道一个key,看看有关于jpg和png文件相关的需要key的隐写,试了个遍发现都没什么用。

再仔细看看提取的png文件,在IEND数据块发现一个异常显眼的数据

image-20250420230021885

这是Oursecret加密的特征,于是使用工具进行解密,密码就是上面的key

image-20250420230136224

flag{6f6bf445-8c9e-11ef-a06b-a4b1c1c5a2d2}

No.shArk

下载附件是个流量包,丢进wireshark,先导出相关数据包

image-20250420231601107

根据这些文件猜测,应该有snow隐写,而w1.html文件如下

image-20250420231701457

暂时推测该文本存在snow隐写,于是需要密码。

将png文件丢进010editor查看,得到一个key

image-20250420231804577

刚开始我用这个key进行snow隐写解密,发现解不出来。可能该key不是这个snow隐写的密码,于是将jpg放进silenteye进行隐写提取,使用上述key,得到:

image-20250420231940251

进行关键词搜索发现

image-20250420232153348

可能是猫脸变换。(相关博客:Arnold阿诺德置乱(猫脸变换)图像盲水印注入预处理(python) - HOr7z - 博客园

博客中的图片:

image-20250420232317054

而文件中的png:

image-20250420232343499

有异曲同工之妙,于是找网上的脚本进行解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
from PIL import Image

def arnold_decode(image, shuffle_times=10, a=1, b=1, mode='1'):
image = np.array(image)
decode_image = np.zeros(shape=image.shape, dtype=image.dtype)
h, w = image.shape[0], image.shape[1]
N = h
for _ in range(shuffle_times):
for ori_x in range(h):
for ori_y in range(w):
new_x = ((a*b+1)*ori_x + (-b)* ori_y)% N
new_y = ((-a)*ori_x + ori_y) % N
if mode == '1':
decode_image[new_x, new_y] = image[ori_x, ori_y]
else:
decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
return Image.fromarray(decode_image)

img = Image.open('C:\\Users\\Lucky\\Desktop\\competition\\hubu群星杯\\misc\\No.shArk\\202410191641147091.png')
decode_img = arnold_decode(img, shuffle_times=5, a=7, b=3)
decode_img.save('C:\\Users\\Lucky\\Desktop\\competition\\hubu群星杯\\misc\\No.shArk\\flag-output.png')

得到一半flag

image-20250420234930304

另一半就是snow隐写,但是密码在哪里呢?

仔细观察流量包,发现udp数据包中有许多01编码,

image-20250420235128654

这是dns外带流量,我们提取出来这些01字符

1
tshark.exe -r complete.pcapng -T fields -Y "ip.dst == 114.114.114.114 && dns.qry.type == 1" -e dns.qry.name > data.txt

image-20250420235805899

得到文件后,将不要的部分删去,再删去重复行,得到:

image-20250421001103424

定睛一看,像个二维码,于是使用excel表来导入文件进行手动转换成二维码。

首先需要将每一行的每一个0和1之间用空格隔开(嫌麻烦可以使用在线工具或脚本)

image-20250421005343125

然后新建一个excel表,找到“数据”->”获取数据”,导入该文本数据,记得使用空格分隔

然后用“条件格式”来让等于1的单元格填充黑色背景,等于0的单元格的字体变成白色。结果如下:

image-20250421005652630

手动添加右上角和左上角,得到完整二维码

image-20250421005833330

扫描一下得到:

image-20250421010005951

这就是snow隐写的密码,将w1.html文件修改后缀为txt,然后使用上述密码进行解密得到

image-20250421010250339

将两个部分合在一起就是

flag{46962f4d-8d29-11ef-b3b6-a4b1c1c5a2d2}

re

ez_rc4

反汇编伪代码

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
int __fastcall main(int argc, const char **argv, const char **envp)

{

unsigned int v3; // eax

__int64 v5[4]; // [rsp+20h] [rbp-30h] BYREF

int v6; // [rsp+40h] [rbp-10h]

char Str[5]; // [rsp+47h] [rbp-9h] BYREF

unsigned int v8; // [rsp+4Ch] [rbp-4h]



_main(argc, argv, envp);

strcpy(Str, "UCSC");

v5[0] = 0x89B83EC0E7A3CF8i64;

v5[1] = 0x3F0EA83858C85F6Ai64;

v5[2] = 0xAB8A1E39811B5F22ui64;

v5[3] = 0x649F307A6475E9B1i64;

v6 = 0xAB7BBD90;

v8 = 36;

v3 = strlen(Str);

rc4_init(Str, v3);

rc4_crypt(v5, v8);

return 0;

}

简单rc4加密,连名字都没改

解密脚本:

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
def rc4_decrypt(ciphertext, key):

\# RC4算法实现

S = list(range(256))

j = 0

key_len = len(key)



\# KSA阶段

for i in range(256):

​ j = (j + S[i] + key[i % key_len]) % 256

​ S[i], S[j] = S[j], S[i]



\# PRGA阶段

i = j = 0

plaintext = []

for byte in ciphertext:

​ i = (i + 1) % 256

​ j = (j + S[i]) % 256

​ S[i], S[j] = S[j], S[i]

​ k = S[(S[i] + S[j]) % 256]

​ plaintext.append(byte ^ k)



return bytes(plaintext)



\# 原始加密数据(小端序转换)

encrypted_data = b''

v5 = [

0x89B83EC0E7A3CF8, # 注意实际存储是小端序

0x3F0EA83858C85F6A,

0xAB8A1E39811B5F22,

0x649F307A6475E9B1

]

v6 = 0xAB7BBD90



\# 将64位整数转换为小端序字节

for qword in v5:

encrypted_data += qword.to_bytes(8, 'little')

encrypted_data += v6.to_bytes(4, 'little') # 添加最后的4字节



\# RC4密钥

key = b'UCSC'



\# 解密数据

decrypted = rc4_decrypt(encrypted_data, key)

print("Decrypted Data:", decrypted)

print("Printable Result:", decrypted.decode('ascii', errors='replace'))

ez_re

反汇编源码

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
int __fastcall main(int argc, const char **argv, const char **envp)

{

char v3; // al

char Str2[112]; // [rsp+20h] [rbp-D0h] BYREF

char Str1[48]; // [rsp+90h] [rbp-60h] BYREF

char Str[43]; // [rsp+C0h] [rbp-30h] BYREF

char v8; // [rsp+EBh] [rbp-5h]

int i; // [rsp+ECh] [rbp-4h]



_main(argc, argv, envp);

v8 = 10;

strcpy(Str, "n=<;:h2<'?8:?'9hl9'h:l>'2>>2>hk=>;:?");

for ( i = 0; i < strlen(Str); ++i )

{

v3 = xor(v8, Str[i]);

Str1[i] = v3;

}

Str1[strlen(Str)] = 0;

printf(Format);

scanf("%s", Str2);

if ( !strcmp(Str1, Str2) )

puts("win,TQLLLLLLL!!!");

else

puts("sorry,this is not flag");

return 0;

}

进行一个异或操作,然后将输入字符串与异或后的Str1比较,所以解出Str1就成

1
2
3
4
5
original_str = "n=<;:h2<'?8:?'9hl9'h:l>'2>>2>hk=>;:?"

xor_result = ''.join([chr(ord(c) ^ 10) for c in original_str])

print(xor_result)

Simplere

Upx魔改壳,拖入010edition,这里010要用最新版,旧版本还不太行

image-20250421080839775

这里应该是UPX0,UPX1,UPX2,题目进行了魔改,我们改回来

之后upx-d 进行脱壳

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
int __fastcall main(int argc, const char **argv, const char **envp)

{

FILE *v3; // rax

unsigned __int64 v4; // rax

char Str[112]; // [rsp+20h] [rbp-60h] BYREF

unsigned __int8 Buf1[112]; // [rsp+90h] [rbp+10h] BYREF

char Buffer[264]; // [rsp+100h] [rbp+80h] BYREF

void *Block; // [rsp+208h] [rbp+188h]

size_t Size; // [rsp+210h] [rbp+190h]

void *Buf2; // [rsp+218h] [rbp+198h]



_main();

Buf2 = &unk_405080;

puts("Give Me FlllllllaaaaaGGG!");

v3 = __iob_func();

fgets(Buffer, 256, v3);

Buffer[strcspn(Buffer, "\n")] = 0;

Size = strlen(Buffer);

Block = malloc(Size);

memcpy(Block, Buffer, Size);

obfuscate_encode((const unsigned __int8 *)Block, Size, Str);

v4 = strlen(Str);

obfuscate_transpose_xor(Str, v4, Buf1);

if ( !memcmp(Buf1, Buf2, 8ui64) )

puts("Yes You Win!");

else

puts("not");

free(Block);

return 0;

}

里面进行了一次魔改的base58加密,进行了一次异或加密操作,我们要逆向两次操作

\

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
# 处理 Buf2 数据并逆向 transpose_xor

buf2_hex = "72 7A 32 48 34 4E 3F 3A 42 33 47 69 75 63 7C 7D 77 62 65 64 7B 6F 62 50 73 2B 68 6C 67 47 69 15 42 75 65 40 76 61 56 41 11 44 7F 19 65 4C 40 48 65 60 01 40 50 01 61 6F 69 57"

buf2_bytes = bytes.fromhex(buf2_hex.replace(" ", ""))



a1_reversed = []

for i in range(len(buf2_bytes)):

xor_val = i + 1

decoded_byte = buf2_bytes[i] ^ xor_val

a1_reversed.append(decoded_byte)

a1_reversed = bytes(a1_reversed)

a1 = a1_reversed[::-1] # 得到 Base58 编码后的字符串



\# Base58 解码

custom = "wmGbyFp7WeLh2XixZUYsS5cVv1ABRrujdzQ4Kfa6gP8HJN3nTCktqEDo9M"

custom_map = {c: i for i, c in enumerate(custom)}



encoded_str = a1.decode('latin-1')



v9 = 0

while v9 < len(encoded_str) and encoded_str[v9] == custom[0]:

v9 += 1



encoded_part = encoded_str[v9:]



number = 0

for c in encoded_part:

number = number * 58 + custom_map[c]



bytes_list = []

while number > 0:

bytes_list.append(number % 256)

number = number // 256



bytes_list = bytes_list[::-1] # 转换为大端序

original = bytes([0] * v9 + bytes_list)



print("Flag:", original.decode('latin-1'))

flag{0ba878d9-8bb5-11ef-b419-a4b1c1c5a2d2}

crypto

Lunz-ucsc

Wp

思路:

在模 N 的整数环上构造多项式 f = e1e2x - (e1-e2),寻找该多项式的小根(目标是找到 k 的值)根据e_1,e_2两个等式相减将d1和d2之间的差值看成一个小量用copper求解,然后gcd求出因数最后就是rsa解密

代码:

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
import gmpy2

from Crypto.Util.number import *

from hashlib import *



e_1 = 82194997342022315294741053886738801755778309600541058857582819748504178218029586817329075468608972333546628374485521400184402963163262742655834395020461909318434218408759432963056836775067368883981421937545474418669913878385887094077169817430600727448380867839881006626945685264795847634981886115304993041631628136473851886823203348581719499157160024911445745322632851807430667833753655691308910924573857543244114539188236171668917232064732826943767269915781685149029139160527731493869032783128334745336285887381730339030076359989916068723957137190717453844444310295759587221150214466448941257886222442167236946023762817554259376632788561021978493693907106048112804092814216335115732687289796860118449346995430040021434986438850327164942720764221862901423771813050035009824215701858655762362015399936372902250977067504212727000797315107722305123781901826260372964003794563854743545219568742418110422688701046616021356858226697543841486497087747712657259451317463305606428176259820286737051441530790573789113667728829662206604792772338461257413364281114387773723898692579006356294992480087943719304524239180738165046907648518521903103759650135544600045989005073217092319548855826667005381517104701733412698272841877137931516982117218225608581665569186933249196741845018511834844544414981555035250852425593826008902095047544747578876223640919793897386377693043508302048480183187157844710880574283128792866376629738280715200563980387359301445057462967819370931652504737823852714734612238853018373314636405639783626927974956276625788802184920232287559681505649010715237855787297487

e_2 = 64122187727334478098553301791077235625639260906174457891776938537038285044681517044012845849048601736428558240533921438302916819425025934973225885809211818189790751616476236608428883939142567650575711490758442310747755441704935369315756941517913927278315834043578627420785342974067333803699662844555926254529237244727534375719868122571102263698948560568991199459140903113110377348187789154257211144174068313381527709568528353000832605802816221054845418024982904708393369173181282816476354486665784983515352482857444378869032220101634114432689862478394556055683821860859875850463810707089022600492091988900749494653834344183398165673450567322248851844656051853665140912370242501422363643802099433464075348279168351216470702507184763811726619347630962848378345030258733023745716937574829941575439968121681130680029035679914270839488865298630191761404554917682318359040105408094069383752609384033750252033273237367286348132901330911746731313028201201829666439171480126966221386235253378104056860492430887542911057069064922503106602377697366238713631664125691688326647247196130005020196785674542444226248879704053916958067659235282907317204189657563756472135321212749728394030855236171882022720575781530559713342982915738876377997138645803111586794930317674671418213235709512822108628762122163509180516396190714181745562401480690794695504357318149941173322387551473154391773590129902904460707063967175869896093589115072753154541601856678428639567972972389015662258203030116017981880452852617106573566546377979964809041695581443921846407962542002308657128638193946859286314988046797

N = 102656930531199322819741252140491678150105419351766529874538711748132275448564771307360722552171375537683026622007355914428283082151916898177289187070426072926291492106641465649627537434157794722917637260699145843389666840049543908412560095077959882211825589332132276599874303904283043025693548669833873341870047913912621999637061842614129757738747471830515353303238598879492119215053598915979966987713596972485340880154399968932115163217865869501900443280198904159123615920434314722813266331356594627291390991620917101278912357563179937601640979627848865210601775650344306736790660313701201486095040763386101953164215547418558711931427566991637431502571542506126879340718877092334161213153414264305178444441322105028075272279719803323772887474280200116446155546883207025336629510198040921223947383148351118538936955587960864699371195348577704440637074984902582268297801426869733610791961700442325884107928801102939917348485659494161445611191032702931411943373025507028646608480404465118888160612254835642636918338195945924532076785555869644175634740376183788776866070595763835540459363210791067561851748019066365740696901460972148810521955774439455698118188397251439004448479552774584082231580786287223325608043496702909467028213189269213006257671486253673702248484360808080232590794281657899229350170579208321802542550971074214257670667703073786809404057399870771729816128206631959677706575636288453480381200130995605281214558104790905688084300620250244986530313845558200328099836053926424927054258719918440283781321096404237444926632626277340511034942882920173700503615281267616906850831057065875864766486942097938244757579499498498158569941529737537

c = 111039757154994940584340532334116972416069873553536764934313111792022839617044953410289031679957972488548299616330346859773349403234979916275715896896



PR.<x> = PolynomialRing(Zmod(N))

f=e_1*e_2*x-(e_1-e_2)

f=f.monic()

k=f.small_roots(beta = 0.5, epsilon = 0.4, X = 2^1000)[0]

pp=gmpy2.gcd(e_1*e_2*int(k)-(e_1-e_2),N)



for g in range(10, 30):

tmp = gmpy2.iroot(pp, g)

if isPrime(int(tmp[0])):

​ p = int(tmp[0])

​ q = N // p**(g+2)

​ d = inverse(65537, (p-1)*(q-1))

​ m = pow(c, d, p*q)

​ message = long_to_bytes(int(m))

​ print(message)

​ flag = 'flag{' + md5(message).hexdigest() + '}'

​ print(flag)

flag{834b3dd2e9d02fad094377b5c5bd7425}

Ez_Calculate-ucs

Wp

思路:flag1是rsa,flag2是背包加密

根据数论计算,爆破k求p,q,代码如下

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
import gmpy2

import libnum

from Crypto.Util.number import *



e = 0x10000

c = 74962027356320017542746842438347279031419999636985213695851878703229715143667648659071242394028952959096683055640906478244974899784491598741415530787571499313545501736858104610426804890565497123850685161829628373760791083545457573498600656412030353579510452843445377415943924958414311373173951242344875240776

n = 86262122894918669428795269753754618836562727502569381672630582848166228286806362453183099819771689423205156909662196526762880078792845161061353312693752568577607175166060900619163231849790003982326663277243409696279313372337685740601191870965951317590823292785776887874472943335746122798330609540525922467021



problem1 = 24819077530766367166035941051823834496451802693325219476153953490742162231345380863781267094224914358021972805811737102184859249919313532073566493054398702269142565372985584818560322911207851760003915310535736092154713396343146403645986926080307669092998175883480679019195392639696872929250699367519967334248

problem2 = 20047847761237831029338089120460407946040166929398007572321747488189673799484690384806832406317298893135216999267808940360773991216254295946086409441877930687132524014042802810607804699235064733393301861594858928571425025486900981252230771735969897010173299098677357738890813870488373321839371734457780977243838253195895485537023584305192701526016

for k in range(1000):

p=gmpy2.gcd(problem1*pow(e,k)+problem2, n)

if(isPrime(p)):

​ print(p)

​ q=n//p

​ print(q)

​ print((p*q==n))



p = 9586253455468582613875015189854230646329578628731744411408644831684238720919107792959420247980417763684885397749546095133107188260274536708721056484419031

q = 8998523072192453101232205847855618180700579235012899613083663121402246420191771909612939404791268078655630846054784775118256720627970477420936836352759291



再用e,phi不互素模板,直接出flag1

from Crypto.Util.number import *

from sympy import isprime

from math import isqrt

from Crypto.Util.number import *

from sympy import isprime

from math import isqrt

import gmpy2

\# 已知值

problem1 = 24819077530766367166035941051823834496451802693325219476153953490742162231345380863781267094224914358021972805811737102184859249919313532073566493054398702269142565372985584818560322911207851760003915310535736092154713396343146403645986926080307669092998175883480679019195392639696872929250699367519967334248

problem2 = 20047847761237831029338089120460407946040166929398007572321747488189673799484690384806832406317298893135216999267808940360773991216254295946086409441877930687132524014042802810607804699235064733393301861594858928571425025486900981252230771735969897010173299098677357738890813870488373321839371734457780977243838253195895485537023584305192701526016

n = 86262122894918669428795269753754618836562727502569381672630582848166228286806362453183099819771689423205156909662196526762880078792845161061353312693752568577607175166060900619163231849790003982326663277243409696279313372337685740601191870965951317590823292785776887874472943335746122798330609540525922467021

c = 74962027356320017542746842438347279031419999636985213695851878703229715143667648659071242394028952959096683055640906478244974899784491598741415530787571499313545501736858104610426804890565497123850685161829628373760791083545457573498600656412030353579510452843445377415943924958414311373173951242344875240776





\# Given values

p = 9586253455468582613875015189854230646329578628731744411408644831684238720919107792959420247980417763684885397749546095133107188260274536708721056484419031

q = 8998523072192453101232205847855618180700579235012899613083663121402246420191771909612939404791268078655630846054784775118256720627970477420936836352759291

n = p * q

e = 0x10000





\# Compute phi

phi = (p - 1) * (q - 1)



\# Compute gcd(e, phi)

g = gmpy2.gcd(e, phi)

print(f"gcd(e, phi) = {g}")



\# Adjust e and phi

e_prime = e // g

phi_prime = phi // g



\# Compute d'

d_prime = gmpy2.invert(e_prime, phi_prime)



\# Decrypt c

m_prime = pow(c, d_prime, n)

print(f"m_prime = {m_prime}")



\# Now solve m^g ≡ m_prime mod n

\# Since g is a power of 2, we can take roots

m_candidate = gmpy2.iroot(m_prime, g)

if m_candidate[1]: # If exact root

m = m_candidate[0]

flag1 = long_to_bytes(m)

print(f"flag1 = {flag1}")

else:

print("Failed to find exact root. Trying other methods...")

\# Alternative: Tonelli-Shanks for modular roots

\# Or brute-force possible roots

\# Here we assume g is small enough to brute-force

for k in range(1, 1000):

​ m_candidate = m_prime + k * n

​ root = gmpy2.iroot(m_candidate, g)

​ if root[1]:

​ m = root[0]

​ flag1 = long_to_bytes(m)

​ print(f"flag1 = {flag1}")

​ break

else:

​ print("Still failed to find m.")



flag1 = b'CRYPTO_ALGORIT'



Flag2的背包加密直接上模板

from gmpy2 import *

from hashlib import md5

from Crypto.Util.number import *

from sympy import *



R = [10, 29, 83, 227, 506, 1372, 3042, 6163]

A = 1253412688290469788410859162653

B = 16036

M = [10294, 12213, 10071, 4359, 1310, 4376, 7622, 14783]

S_list = [13523, 32682, 38977, 44663, 43353, 31372, 17899, 17899, 44663, 16589, 40304, 25521, 31372]



\# Step 1: Recover R

A_inv = inverse(A, B)

R_recovered = [mi * A_inv % B for mi in M]

assert R_recovered == R # Should be true



\# Step 2: Decrypt S_list

bits = []

for S in S_list:

S_prime = S * A_inv % B

\# Solve knapsack with R and S_prime

bits_group = []

for ri in reversed(R):

​ if S_prime >= ri:

​ bits_group.append(1)

​ S_prime -= ri

​ else:

​ bits_group.append(0)

bits_group = bits_group[::-1]

bits.extend(bits_group)



\# Step 3: Convert bits to bytes

flag2 = []

for i in range(0, len(bits), 8):

byte_bits = bits[i:i+8]

byte = int(''.join(map(str, byte_bits)), 2)

flag2.append(byte)

flag2 = bytes(flag2)

print(f"flag2 = {flag2}")



flag2 = b'HMS_WELL_DONE'

结合flag1和flag2出Flag

from hashlib import *

flag1 = b'CRYPTO_ALGORIT'

flag2 = b'HMS_WELL_DONE'

flag = 'flag{' + md5(flag1+flag2).hexdigest()[::-1] + '}'

print(flag)

flag{64f67374264b7621650b1de4dbc5f924}