[TOC]
web
signphp-ucsc
签到题,直接开启环境,然后直接找到flag文件,拿到flag
ezLaravel-ucsc
开启环境,然后直接目录扫描,看到flag.php
访问该文件,拿到flag
(这道题是出题人权限访问没控制好,导致直接扫描目录就能访问/flag.php文件。由于赛后环境无法开启,所以无法再复现了)
upload2
打开网站,看到是文件上传页面,先查看源码,发现是白名单过滤,只允许上传图片文件。
先将一句话木马改成.jpg,上传抓包修改后缀,发现响应包提示图片格式错误。
然后修改一句话木马文件,加上图片前缀(GIF89a),再次上传,显示上传give_me_flag.php。
根据提示,猜测是后端匹配了文件名,需要修改上传文件的文件名。
修改后再次上传,返回提示:文件里面需要givemeflag的内容。
于是使用记事本编辑,加上该内容,然后继续上传得到flag
flag{789d153e-189b-408f-93e4-a1ae286bef3c}
文件内容:
easyphp
打开界面,直接f12查看网络包,找到一个flag的头部,是个base64编码,解码得到flag。
headache
打开界面
根据描述,flag在响应包的header里,抓包,看到一串base64代码,解密都得到flag
Misc
本次校内赛道只有一个misc题目,但是文件里面却有三个misc文件,也就是三个misc题目随便找一个flag提交就可以了(难度大大减小)。
这里我说下三道题的思路。
three
下载附件,有三个part文件和一个流量包,先看第一个
明显盲水印,提取盲水印,得到part1: 8f02d3e7
然后看第二部分,二进制解码得到part2: -CE89-4D6B-830E-
然后看第三部分,是个压缩包,需要密码。
密码应该在流量包里面,进行流量分析,看到一堆密码本
挨个试试,然后发现密码是thinkbell
解压拿到part3: 5d0cb5695077
将上述part合在一起得到:
flag{8f02d3e7-CE89-4D6B-830E-5d0cb5695077}
提交发现错误,然后观察flag,发现第一、三部分都是小写,于是将第二部分改写成小写:
flag{8f02d3e7-ce89-4d6b-830e-5d0cb5695077}
提交成功。
小套不是套
附件里有个二维码和两个压缩包,其中两个压缩包都需要密码。
先扫描一下二维码
拿到密码:PassW0rd is !@#QWE123987
解压第一个压缩包,得到内层压缩包。将其放进010editor查看,发现是伪加密,于是修改回来,解压得到一张jpg图片
然后放进010editor,查看一下
找到一个位置单元数据,且有IHDR数据,说明这是一个png文件的一部分数据。
将这部分提取出来,然后加上png文件头部(89 50 4E 47 0D 0A 1A 0A),得到一个png文件、
进行各种png文件分析也没什么头绪,于是看最后一个压缩包。
发现压缩包内的文件大小都一样,于是想到CRC32爆破
爆破出来得到一个base64编码:
1 2 3 R1JWVENaUllJVkNXMjZDQ0pKV1VNWTNIT1YzVTROVEdLVjJGTVYyWU5NNFdRTTNWR0ZCVVdNS1hNSkZXQ00zRklaNUVRUVRCR0pVVlVUS0VQQktHMlozWQ== 解码: Key is SecretIsY0u
现在知道一个key,看看有关于jpg和png文件相关的需要key的隐写,试了个遍发现都没什么用。
再仔细看看提取的png文件,在IEND数据块发现一个异常显眼的数据
这是Oursecret加密的特征,于是使用工具进行解密,密码就是上面的key
flag{6f6bf445-8c9e-11ef-a06b-a4b1c1c5a2d2}
No.shArk
下载附件是个流量包,丢进wireshark,先导出相关数据包
根据这些文件猜测,应该有snow隐写,而w1.html文件如下
暂时推测该文本存在snow隐写,于是需要密码。
将png文件丢进010editor查看,得到一个key
刚开始我用这个key进行snow隐写解密,发现解不出来。可能该key不是这个snow隐写的密码,于是将jpg放进silenteye进行隐写提取,使用上述key,得到:
进行关键词搜索发现
可能是猫脸变换。(相关博客:Arnold阿诺德置乱(猫脸变换)图像盲水印注入预处理(python) - HOr7z - 博客园 )
博客中的图片:
而文件中的png:
有异曲同工之妙,于是找网上的脚本进行解密:
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
另一半就是snow隐写,但是密码在哪里呢?
仔细观察流量包,发现udp数据包中有许多01编码,
这是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
得到文件后,将不要的部分删去,再删去重复行,得到:
定睛一看,像个二维码,于是使用excel表来导入文件进行手动转换成二维码。
首先需要将每一行的每一个0和1之间用空格隔开(嫌麻烦可以使用在线工具或脚本)
然后新建一个excel表,找到“数据”->”获取数据”,导入该文本数据,记得使用空格分隔
然后用“条件格式”来让等于1的单元格填充黑色背景,等于0的单元格的字体变成白色。结果如下:
手动添加右上角和左上角,得到完整二维码
扫描一下得到:
这就是snow隐写的密码,将w1.html文件修改后缀为txt,然后使用上述密码进行解密得到
将两个部分合在一起就是
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要用最新版,旧版本还不太行
这里应该是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 = e1e2 x - (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}