re
1.encode
-
该题如果理解的题目的意思本身没什么难度,主要是运用了心理学原理藏起来加密函数,该题的scanf函数是题者写的,所以scanf藏了一个enc函数(可知为一个TEA加密)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24__int64 __fastcall enc(__int64 a1, int a2, __int64 a3) { int v4; // [xsp+10h] [xbp-140h] int v5; // [xsp+14h] [xbp-13Ch] int m; // [xsp+18h] [xbp-138h] int i; // [xsp+1Ch] [xbp-134h] int j; // [xsp+1Ch] [xbp-134h] int k; // [xsp+1Ch] [xbp-134h] _BYTE v11[256]; // [xsp+38h] [xbp-118h] v5 = 8 - a2 % 8; v4 = a2 + v5; for ( i = 0; i < a2; ++i ) v11[i] = *(_BYTE *)(a1 + i); for ( j = a2; j < v4; ++j ) v11[j] = v5; for ( k = 0; k < v4; k += 8 ) { for ( m = 0; m < 8; ++m ) *(_BYTE *)(a3 + k + m) = v11[k + m]; enc_block(a3 + k, (__int64)&a); } return (unsigned int)v4; } -
main函数中还有一个异或和bsae64,简单查找可得密文和映射表
-
解密可得SYC{St4nd4rd_Funct10n_N0t_4lw4ys_St4nd4rd}
2.ez_pyyy
-
下载附件发现获得了.pyc文件
-
找一个在线反编译网站,反编译获得py代码
-
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 36cipher = [ 48,55,57,50,53,55,53,50,52,50,48,55,101,52,53,50,52,50, 52,50,48,55,53,55,55,55,50,54,53,55,54,55,55,55,53,54, 98,55,97,54,50,53,56,52,50,52,99,54,50,50,52,50,50,54] def str_to_hex_bytes(s = None): return s.encode('utf-8') def enc(data = None, key = None): return None((lambda .0 = None: [ b ^ key for b in .0 ])(data)) def en3(b = None): return b << 4 & 240 | b >> 4 & 15 def en33(data = None, n = None): '''整体 bitstream 循环左移 n 位''' bit_len = len(data) * 8 n = n % bit_len val = int.from_bytes(data, 'big') val = (val << n | val >> bit_len - n) & (1 << bit_len) - 1 return val.to_bytes(len(data), 'big') if __name__ == '__main__': flag = '' data = str_to_hex_bytes(flag) data = enc(data, 17) data = bytes((lambda .0: [ en3(b) for b in .0 ])(data)) data = data[::-1] data = en33(data, 32) if data.hex() == cipher: print('Correct! ') else: print('Wrong!!!!!!!!') -
该代码虽然无法编译但是可以看的出是如何加密的,然后再根据加密过程反推出解密过程
-
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 40def en3(b): return (b << 4 & 240) | (b >> 4 & 15) def de33(data, n): bit_len = len(data) * 8 if bit_len == 0: return b"" n = n % bit_len val = int.from_bytes(data, 'big') val = (val >> n | val << (bit_len - n)) & ((1 << bit_len) - 1) return val.to_bytes(len(data), 'big') cipher = [ 48,55,57,50,53,55,53,50,52,50,48,55,101,52,53,50,52,50,52,50, 48,55,53,55,55,55,50,54,53,55,54,55,55,55,53,54,98,55,97,54, 50,53,56,52,50,52,99,54,50,50,52,50,50,54 ] # Step 1: 转为 hex 字符串 hex_str = ''.join(chr(x) for x in cipher) print("Expected hex:", hex_str) # Step 2: 解析为二进制数据(en33 输出) enc_data = bytes.fromhex(hex_str) # Step 3: 逆向 en33(data, 32) reversed_bytes = de33(enc_data, 32) # Step 4: 逆向 [::-1] after_swap_nibble = reversed_bytes[::-1] # Step 5: 逆向 en3 (nibble swap) after_xor = bytes(en3(b) for b in after_swap_nibble) # Step 6: 逆向 XOR 17 flag_bytes = bytes(b ^ 17 for b in after_xor) # Step 7: 输出 flag flag = flag_bytes.decode('utf-8') print(flag) -
得到flag:SYC{jtfgdsfda554_a54d8as53}
3.only_flower
-
打开ida发现
JUMPOUT(0x401620); -
进一步查看发现,该处存在
jmp short near ptr loc_40161F+1一条花指令,因为这个+1个字节是跳转到了指令中间,没有正确的跳转到一个指令的开始,会导致反编译出错 -
解决办法,将该指令的第一个字节改为90,即将该指令改为nop
-
对于该题目,可以选择直接不看主函数,赌加密过程全在一个函数里面(正常来说对于主函数也要修复)
-
查看string表,发现除了输出的提示,剩下一个GEEK2025的可疑字符串,双击查看,在交叉引用,发现
.data:00404004 _KEY dd offset aGeek2025 ; DATA XREF: _encrypt+6↑r得到再字符串存在KEY数组内,在对KEY使用交叉引用,发现再一个encrypt使用了,合理猜测该函数就为加密函数了。进入发现
|
|
从这里可以发现通过该种发现找到加密函数属于特例,因为刚好再ida可以编译的范围内使用过KEY,如果出题者有意则可以让做题人无法通过该种方法找到加密函数。在通过交叉引用查找函数时,可以发现在GEEK2025下方还有一个数组
|
|
可猜测大概率该数组存放的时密文,对该数组使用交叉引用则无法找到加密函数
- 修复加密函数:这里可以将所以花指令改为nop,就可以完成该函数的修复,得到
|
|
得到加密函数之后,就可以写出解密脚本
|
|
- 运行得到结果SYC{asdjjasdhjk12wk12ijkejk}
- 附修完之后的main函数
|
|
4.ezRu3t
-
一直观察并结合string表中的两个映射表可知,有一个base64,一个base85,再看顺序是先64在85,并无其他加密所以直接解密可得
-
64表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 85表:!"#$%&’()*+,-./0123456789<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu
密文:<AA;XAM?,_@;T[r@7E779h8;s>’`pt=>3c6ASuHFASOtP<Gkf_A4&gPAl1]S
-
base85解密
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 47import struct import re # 添加导入 def base85_decode(encoded_str, custom_table=None): """简化的Base85解密函数""" if custom_table is None: custom_table = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu" # 创建字符到索引的映射 char_map = {char: i for i, char in enumerate(custom_table)} # 清理输入字符串 encoded_str = re.sub(r'\s+', '', encoded_str) if encoded_str.startswith('<~') and encoded_str.endswith('~>'): encoded_str = encoded_str[2:-2] # 处理解码 result = bytearray() n = 0 count = 0 for char in encoded_str: if char == 'z' and count == 0: result.extend([0, 0, 0, 0]) continue n = n * 85 + char_map[char] count += 1 if count == 5: result.extend(struct.pack('>I', n)) n = 0 count = 0 # 处理最后的块 if count > 0: n *= 85 ** (5 - count) result.extend(struct.pack('>I', n)[:count-1]) return bytes(result).decode('utf-8', errors='ignore') # 使用 encoded_text = "<AA;XAM?,_@;T[r@7E779h8;s>'`pt=>3c6ASuHFASOtP<Gkf_A4&gPAl1]S" # 替换为实际字符串 decoded_text = base85_decode(encoded_text) print(decoded_text) #结果U1lDe09oamhoaF95MHVfZzN0X0V6enp6ejNfUnUzdCFAfQ== -
符合base64的格式在解密可得SYC{Ohjhhh_y0u_g3t_Ezzzzz3_Ru3t!@}
5.ezSMC
- 前置知识:CTF中SMC
简要来说就是一段正常的代码,通过加密过程,使程序变得混乱,从而让IDA等反编译工具无法识别 (广义上可以理解为程序保护壳吧) 一般常见的为异或加密 同时一般伴随着SMC出现的还有 VirtualProtect VirtualProtect 是 Windows 操作系统中的一个 API 函数,它允许应用程序改变一个内存页的保护属性。这个函数的原型如下:
|
|
逆向分析中,VirtualProtect 函数通常用于代码自加密的场景。代码自加密是一种保护代码不被轻易逆向分析的技术,通过在程序运行时动态地修改代码的内存保护属性,使得代码在执行时可以被修改和执行,但在不执行时则不能被读取或修改
- 打开ida观察main函数
|
|
- 下一步只需要通过动态调试解密出正确的加密函数即可得到加密过程
- 只需在代码加密函数运行之后下个断点,再查看
encodee发现内容出现了变化
未解密代码
|
|
解密后代码
|
|
修复之后的encodee
|
|
可知是一个base64加密
-
加密过程input—>与s表异或—->bsae64加密—–>base58加密
-
解密过程密文—>base58解密—->base64解密—->与s表异或
-
bae58解密
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 30import base58 # 这个库默认用标准表,所以我们要自定义映射 # 你的自定义 Base58 字母表 CUSTOM_B58 = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789" # 标准 Base58 字母表(base58.b58decode 用的) STANDARD_B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" # 编码后的字符串 encoded = "tHMoSoMX71sm62ARQ8aHF6i88nhkH9Ac2J7CrkQsQgXpiy6efoC8YVkzZu1tMyFxCLbbqvgXZHxtwK5TACVhPi1EE5mK6JG56wPNR4d2GmkELGfJHgtcAEH7" # 将自定义表的字符映射到标准表 # 方法:构建一个从 自定义字符 -> 标准字符 的映射 trans = str.maketrans(CUSTOM_B58, STANDARD_B58) encoded_std = encoded.translate(trans) # 用标准库解码 decoded_bytes = base58.b58decode(encoded_std) # 输出十六进制和尝试转为字符串 print("解码后的字节 (hex):", decoded_bytes.hex()) # 尝试转为 ASCII 字符串(如果是文本的话) try: text = decoded_bytes.decode('utf-8') print("解码后的字符串:", text) except: print("不是有效的 UTF-8 文本") #由运行结果可得#ZGZkMjRjNmMzM2JlZWUyYjQ5MzI5ZTYxMTg2MDEyYjA1ZGExNTQyZGQzZjA5ZmIwZTlhZWQzMzBjOD#c0NzdjYw== -
base64解密
1 2 3 4 5 6 7 8 9 10 11import base64 print("编码 1 解码 2") x=int(input()) if x==1: s=input() print((base64.b64encode(s.encode('utf-8'))).decode('utf-8')) else: s=input() print((base64.b64decode(s.encode('utf-8'))).decode('utf-8')) #解密可得dfd24c6c33beee2b49329e61186012b05da1542dd3f09fb0e9aed330c87477cc -
算s表,异或解密
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 47def rc4_decrypt(data, key): """ RC4 解密函数 data: 要解密的数据(bytes) key: 密钥(bytes) 返回: 解密后的数据(bytes) """ # RC4 KSA (Key Scheduling Algorithm) S = list(range(256)) j = 0 key_length = len(key) for i in range(256): j = (j + S[i] + key[i % key_length]) % 256 S[i], S[j] = S[j], S[i] # RC4 PRGA (Pseudo-Random Generation Algorithm) + 解密 i = j = 0 result = bytearray() for byte in data: i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] k = S[(S[i] + S[j]) % 256] result.append(byte ^ k) return bytes(result) # 使用示例 if __name__ == "__main__": # 您的密文(32字节数据) ciphertext = bytes.fromhex("dfd24c6c33beee2b49329e61186012b05da1542dd3f09fb0e9aed330c87477cc") # 密钥 key = bytes([17]) # 0x11 # 解密 decrypted = rc4_decrypt(ciphertext, key) print("解密结果 (hex):", decrypted.hex()) # 尝试转换为字符串 try: text = decrypted.decode('utf-8') print("解密结果 (文本):", text) except: print("不是有效的UTF-8文本") print("原始字节:", decrypted) -
运行得到flag:SYC{OHhhhhhhh_y0u_Kn0m_SMCCCC@!}
6.QYQSの奇妙冒险
- 将文件拖入ida中,找到main函数可以看到加密过程为
|
|
- 可知input先异或i,再与key数组异或
- 所以解密过程为QYQS这个密文,先异或key再异或i,解密脚本如下
|
|
- 运行可得:SYC{I_@m_QyqS_r1GhT?}
7.Gensh1n
这题的主要程序其实事在cleanup()函数中,而不是正常的main函数
|
|
观察程序可知,有一步将sub_44656压栈观察这个函数
|
|
可知和是一个标准rc4
所以提取密文并写出解密脚本
|
|
运行结果:解密后的数据: SYC{50_y0u_pl@y_Gensh1n_too}
8.Mission GhostSignal
这是一个misc和re融合的题目,给了一个压缩包,一个exe文件,大概率是通exe文件找到密码,在解压缩
先看main函数
|
|
可知核心加密在 sub_402B57(v5, v4, 32); 密文在byte_406020[j]中
|
|
仔细查看加密函数,和其中调用的函数还有猜测是AES加密,不一样的是这个的AES
中的V5是程序生成的,需要动调获得。解密脚本如下
|
|
输入密文 hex(无空格):B2B3DCB9F8D693FFB5A1CC2A6FDE2744AF2198DD00C10D1C5306813E16ABDF13 解密明文(ASCII): We_ve_Trapped_in_The_Sink
现在已经获得了密码解密压缩包可得一个音频文件
打开听一下发现声音十分刺耳大概率是SSTV
转成图片是
扫描后是一个网盘文件,下载后是一个压缩包,好像是一个伪加密,改一下二进制文件,解压之后就是标准的摩斯电码了最后结果SYC{7h15_1S_4_9r4nD_c0N5p1r@cY.}
9.QYQSの奇妙冒险2
直接反编译之后看data就可以直接找到SYC{M@y_bE_y0u_F1nd?}
10.stack_bomb
这题如果加密不熟悉但有耐心的话,可以动调一行一行看汇编干了什么,我就是这么做的有点肝不推荐
加密过程的手记:
后四小端序拼接整数左移4加1 =a—>var_6c
后四小端序拼接整数+9*i后000000 =b
a^b=c —->var_6c
(var_18小端序拼接整数左移4加1)^(var_18小端序拼接整数+9*i后000000) —->var_6c
(var_18拼接整数左移5位再加2)^var_6c=e
e+var_c小端拼接整数 —->var_c
var_c左移4+3—->var_6c
(var_c+9*i后000000)^var_6c——->var_6c
(var_c右移5(省略前导零后的简化写法)+4 )^var_6c+var_18小端整数—–>var_18
var_18(第一次为后四位)
var_c(第一次为前四位)
建议写个代码复现一下,对了在解密。
解密脚本如下
|
|
运行完之后flag被拆成四块,拼接一下可得syc{QYQS_F1nD_Th3_@nswer_H3re~~}
11.ez_vm
这题可以黑盒
先动调出密文
|
|
得到
|
|
然后看程序
|
|
其中有异或的字眼
可以先试试黑盒,已知flag的前四位是SYC{
已知了密文,黑盒解密如下
|
|
运行结果
找到所有符合条件的潜在解(按加密类型分类):
- 2字节密钥异或(key=0x5a,0x5a): SYC{W31c0m3_t0_r3@1_r3verse!}
- 4字节密钥异或(key=[‘0x5a’, ‘0x5a’, ‘0x5a’, ‘0x5a’]): SYC{W31c0m3_t0_r3@1_r3verse!
注意多解,第一次单字节异或就出了一个
12.GeekBinder
这题可以不了解binder,直接看.so文件
可以找到
|
|
|
|
一眼异或,注意密文复原的时候后两句的小坑
解密脚本如下
|
|
结果SYC{An@Iyz1ng_Th3_proc3ss3s_B3Tween_File3_1s_contr@ry_To_n0rm@l_pr@ctic3_1n_Re_eng1neer1ng}
13.国产の光
把.hap文件改为.zip解压之后在ets中找到.abc文件,反编译一下找到如下代码
|
|
加密过程清晰写出解密脚本
|
|
运行结果SYC{HarmonyOS_1s_right?right!}
14.Lastone
先通过string表找到主体
|
|
这题目的密文好找,难在加密。加密函数是 sub_4012D5(Buffer);
|
|
可以看到最核心的地方就是通过off_40C000[dword_40C508 & 0xF](a1 + 4 * j, 4, (v8 + v6 * v7) ^ (40503 * v9));off_40C000这个函数表调用了函数。
比较笨的方法可以像我一样一个个看,然后记录干什么,在动态调试出每一轮的所传入的数据
0 sub_4015C0 逐字节 XOR 密钥(按i%4取密钥不同字节)
1 sub_401670 逐字节加密钥(按i%4取密钥不同字节)
2 sub_401720 循环左移n位(n=a3&7)
3 sub_4017F0 逐字节减密钥(按i%4取密钥不同字节)
4 sub_4018A0 交换首尾字节(长度≥2)
5 sub_F41940 4 字节块加(key-1640531527)^(16key+41793)
6 sub_F41A40 反转字节数组(按长度)
7 sub_F41B00 字节 = BYTE1(key) + (key^原字节),key 左移 1 位
8 sub_F41BC0 交换首尾字节 + 末尾字节按(HIBYTE(key)+(key^首字节))^首字节修改
9 sub_F41C90 S 盒替换(高低 4 位)+ XOR 密钥对应字节
10 sub_F41E20 逐字节乘 (key 1)(奇数)
11 sub_F41EC0 循环移位(偏移key%Size)
12 sub_F41FD0 逐字节 XOR 动态密钥(密钥 = 前一字节加密后的值)
13 sub_F42080 字节 = HIBYTE(key) ^ (8原字节) ^ (key*原字节)
14 sub_F42130 字节按位反转 + XOR 密钥对应字节
15 sub_F42250 逐字节 XOR 动态密钥(密钥 = 右移 1 位 + 进位位)
dword_F4C508 &0xF,0xd ,0x4, 0x0, 0xc ,0x4 ,0x6 ,0x3, 0x0
(v8 + v6*v7) ^ (40503 * v9)0x83a2d5,0x46bbac56,0xc5f1e, 0x1ee214 ,0x7431ed ,0x11ba8d6 ,0x20c619 ,0x3488718 密文0x35, 0x67, 0x05, 0x2D, 0x74, 0x40, 0x53, 0x31, 0x41, 0x6F, 0x62, 0x45, 0x4B, 0x1F, 0x57, 0x36, 0x5F, 0x4B, 0x73, 0x6E, 0x4F, 0x6C, 0x5F, 0x49, 0x5D, 0x7F, 0x3F, 0x79, 0x28, 0xD2, 0x69
然后就可以解密了
SYC{1@St_0nE_THanKs_I_lOvE_y0U!}
15.obfuscat3
|
|
这题核心在加密用了混淆导致很难看懂
|
|
多读读多看看可以知道加密基于 RC4 流加密算法的自定义变体
写出解密脚本
|
|
由运行结果可知SYC{Alright_I_sti1l_h0pe_th3t_you_solved_the_chall3nge_by_deobfuscating_them_Geek_is_just_the_first_step_of_your_CTF_journey_Im_glad_I_could_be_part_of_your_growth_Good_luck_for_y0u!}
pwn
16.Mission Calculator
打开ida查看程序逻辑发现
|
|
发现只要满足程序逻辑就可以获得flag,也就是接受数据,做乘法返回数据
exp脚本如下
|
|
交互即可获得flag
17.Mission Cipher Text
打开ida,找到溢出点
|
|
exp如下
|
|
这题还有个注意的是,程序在read之前把标准输出文件关了,所有在交互的时候要想获得flag就需要重定向一下才可以获得flag
18.次元囚笼
打开ida看main函数
|
|
通过read函数找溢出点
|
|
要进入这个函数要先进入abandon_me()函数中
所以根据运行逻辑就可以构造出每一次的发送,exp如下
|
|
misc
19.🗃️🗃️
通过搜索引擎搜索可知是北京天坛公园
按格式上交可得flag
20.Bite off picture
下载附件获得一个压缩包,直接解压发现不行有密码,根据提示打开010,拖到最下面发现==gcyV2dyV2d是一个倒着的base64转置之后d2Vyd2Vycg==,解密可得werwerr验证发现确实为解压密码。
解压后有个wow照片,先用crc爆破看看长宽是否正确
|
|
运行结果
1002 956 hex: 0x3ea 0x3bc
在打开010,发现长宽确实不对,修改之后即可得到正确的图片,从修正后的图片可以看到flagSYC{mi3c_13_really_fun!!!!!}
21.Blockchain SignIn
先在以太坊查询该交易
找到inputdata内容0x5359437b773362335f67346d335f73743472747d
直接对应ASCII转化可得到
SYC{w3b3_g4m3_st4rt}
22.1Z_Sign
- 打开 Etherscan交易页面
- 向下滚动到"Logs"部分
- 寻找"Pool Created"或类似事件
- 查看事件参数,找到fee值
- 将fee转换为题目要求的格式
SYC{0.3%}(如果fee=3000)

所以flag是SYC{0.99%}
23.Dream
直接查找合约代码段,查看可疑数据就可以获得flag
24.hidden
这个flag被拆成了三段
第一段在word文档里,在搜索框中搜索隐藏段落标记,把它打开,之后可以看到第一个flag:SYC{adsad
根据提示word的本质是什么?可知下一步需要讲文件格式改为zip格式,修改解压后在doc文件中可以找到flag3:sjdmd}
在旁边的.text文件里有一个base64编码,解密之后可得362geydgwunkdwee
最终将3个flag拼接可得最终flag:SYC{adsad362geydgwunkdweesjdmd}
25.gift
依旧获得一个压缩包,依旧需要密码,打开010发现密码就在最下面ZzFmdA==,解码可得g1ft,解压之后有一个名为watermark.BMP的图片,根据提示搜索watermark软件,即可获得flag SYC{IT3_gift-f0r-you}
26.4ak5ra
获得一个压缩包正常解压无密码,获得一个提示和一个图片,提示我们需要找到原头像,这个头像大概率是藏在现在的头像中,然后尝试分离文件,发现确实分离出一个图片,在根据主题目提示的LSB,对原头像使用可得,flag:SYC{Im_waiting_for_Sakura_t0_become_a_top_pwn_master}
27.问卷
直接填写问卷即可获得flag
28.HTTP
1.下载附件,文件是 traffic (1).pcapng ,是网络流量包文件,用Wireshark打开
2.过滤http协议,定位http包 3.提取http包数据段,重点看http请求和响应的body。此题正好藏在GET /pixel.gif?d=…里的d参数,查看完整内容 4.解码发现所得目标信息不完整,继续查看其他几段参数,拼接得d=U1lDe1JfVV9BXw==RjBSM05TMUM1X01BU1RFUj99 5.解码获得flag:SYC{R_U_A_F0R3NS1C5_MASTER?}
Crypto
29.ez_xor
这是一道基于 RSA 的密码学题目,核心考点是利用数论性质分解 RSA 的模数因子:
- 分解 p 和 q:已知
n=p*q和gift=p^q(异或),利用公式p*q = [(p+q)/2]^2 - [(p^q)/2]^2求解p+q,进而分解p和q。 - 分解 s 和 r:已知
gift1=s&r(与)、gift2=s^r(异或),利用公式s+r = (s^r) + 2*(s&r)得到s+r,结合N/n=s*r求解s和r。 - RSA 解密:得到所有素因子后,计算欧拉函数
φ(N),求私钥d并解密。
exp如下
|
|
运行可得syc{we1c0me_t190_ge1k_your_code_is_v1ey_de1psrc!}
30.Caesar Slot Machine
具体解密步骤
解密凯撒密文:尝试移位 1-25,找到能还原出 A: 、B: 、P: 的明文,提取 a、b、P。 计算不动点 x: 若 a ≠ 1:计算 x = b * pow(1 - a, -1, P) % P(模逆元)。 若 a = 1:若 b = 0,任意 x 均可;否则无解(但题目中服务器可能保证有解)。 发送 x:将计算得到的 x 发送给服务器,通过本轮验证。 重复 30 轮:每轮重复上述步骤,最终获取 Flag。
|
|
31.pem
核心步骤
检查文件大小:/mnt/data/enc 为 64 字节,表示单块 RSA 密文(与私钥模长匹配)。
尝试常规解密:用 cryptography 或 openssl 尝试 OAEP(SHA-1/SHA-256)和 PKCS#1 v1.5 —— 全部失败(padding check failed)。
怀疑 raw RSA(无填充):当填充校验失败且密文长度等于模长时,可能使用了未填充的 RSA(或把签名当密文)。
执行 raw 私钥运算:用私钥的私有指数 d 计算 m = c^d mod n,并把结果按模长转为字节、去掉前导零。
读取并确认明文:结果为 UTF-8 可读字符串,即 flag:SYC{PEM_1s_n0t_only_S5l}。
快速复现(一行概念)
用 Python 载入私钥与密文,计算 m = pow(int.from_bytes(ct,‘big’), d, n),再转回字节并去前导零,即为明文。SYC{PEM_1s_n0t_only_S5l}
32.baby_rabin
分析task文件可得是一个RSA加密的变种
|
|
运行可得syc{th1s_so_1z_mum_never_ca1r_mytstu1d}#
33.dp_spill
解密脚本如下
|
|
最好在Liunx下运行脚本,会快一点
SYC{644684707c540998d760975fb98a816a469ec567abe5c8004164d3ce887c6a8e}
34.S_box
核心逻辑拆解
-
关键信息提取
:服务器交互时直接发送 3 个核心参数(无任何隐藏):
- AES 密钥:
key1(128 位整数,可直接转字节数组) - AES 密文:
Cipher(flag 的加密结果) - CBC 模式向量:
IV(16 字节随机值)
- AES 密钥:
-
AES 解密条件满足:AES-CBC 解密仅需「密钥 + IV + 密文」,三者均已公开,无需依赖自定义加密函数或交互功能。
-
直接解密操作
:
- 将
key1(整数)转字节数组(long_to_bytes(key1))作为 AES 密钥; - 用 AES-CBC 模式解密
Cipher; - 对解密结果执行 PKCS7 去填充(
unpad),得到原始 flag。
- 将
关键
自定义加密函(Encrypt)和 16 位交互次数是干扰项,核心矛盾已通过服务器泄露的 AES 密钥直接解决,无需分析 S 盒、置换等复杂逻辑。
|
|
运行结果SYC{SS_B0xx_I1s_ver1y_Differe1c999c}
web
35.阿基里斯追乌龟
1.直接点击追赶,最终追上但回显是虚假的flag 2.开发者工具修改源代码把阿基里斯的位置改成200,乌龟位置改成100.本地覆盖,刷新 3.再点追赶获取真实flag:SYC{Spi1t_th3_T1me_t0_the_3nd_019aba97fc4c7c3d8d05c30b00db6f2b}
36.Vibe SEO
1.开启环境进入发现只是png.第一想到图片隐写,尝试后发现并不是,再次审题干,关注题目中“结构化的站点地图”,站点地图是网站向搜索引擎提供的结构化页面索引文件(通常命名为 sitemap.xml 、 sitemap.txt 等)。 2.尝试拼接站点地图相关路径http://819a268a-232f-7e31-9016-301e2c38c692.geek.ctfplus.cn/sitemap.xml,成功 3.从这个 sitemap.xml 的源码中可以提取到关键路径http://localhost/aa__^^.php,核心思路是替换路径中的localhost为题目域名,访问目标文件。尝试构造URL为http://019abae6-0385-75ee-a05e-21775d87bf24.geek.ctfplus.cn/aa__%5E%5E.php 4.从页面回显可以发现存在一个filename参数,尝试文件读取漏洞,通过filename参数传递文件路径。尝试一系列读取常见的Flag路径:http://xxx.geek.ctfplus.cn/aa__^^.php?filename=flag.txt无果,但回显显示filename to long 5.于是读取当前文件的源码(看是否内嵌Flag):http://019a268a-232f-7e31-9016-301e2c38c692.geek.ctfplus.cn/aa__^^.php?filename=aa__^^.php。如下