文章总结: 文档介绍了2025KCTF比赛第二题《初窥门径》的设计思路和解法,这是一个结合质因数分解、三维迷宫建模与逆向分析的CTF题目。文章详细解释了题目设计原理、源码结构,并提供了两种解题方法:AI辅助解题和传统手工逆向分析。评委指出题目在坐标约束上存在疏漏导致多解问题,建议在坐标转换时严格与维度对齐或增加双重校验,以使题目更严谨。
综合评分: 86
文章分类: CTF,逆向分析,二进制安全,漏洞分析,AI安全
2025 KCTF | 第二题《初窥门径》设计思路及解析
2025 KCTF
看雪学苑
2025年8月18日 18:15
上海
2025 KCTF于8月15日中午12点正式开赛!比赛设置了多维度的评分体系,包括难度值、火力值和精致度积分。今天中午12点,第二题《初窥门径》已截止答题。
*注意:签到题《废柴少年觉醒》持续开放,整个比赛期间均可提交答案获得积分
本题共有32支战队成功提交flag,其中前3名分别是:【时空旅人】:47分47秒;【COMPASS】:48分34秒;【山东安在】:1小时1分36秒。
KCTF评委团队点评:
这道题综合了质因数分解、三维迷宫建模与轻度逆向干扰,设计思路巧妙:
通过质数分解恢复迷宫,再利用路径映射字符获取结果,既考察空间建模与图算法,也锻炼选手对函数拆分和 ret 跳转的分析能力,整体兼具趣味性与技术性。
但题目在坐标约束上存在疏漏:y 轴仅做 %12 判断,x 轴取模与数据范围不一致,导致实际出现多解。若在坐标转换时严格与维度对齐或增加双重校验,并辅以最短路径唯一化或哈希校验,将能有效避免多解问题,使题目更严谨、更具教学价值。
一起来看看本题的设计思路和解题思路吧~
一、
设计思路
出题战队:野鹿子
战队成员ID:yegu、mesetop
题目描述文档:
此题使用《规则:5.1.1 Windows方案一》,需要你输入一串序列号。
最终cm.exe文件的SHA1值为:db4b7754816c6ba61f8a9687feb2d50203941958
判胜条件:
打开cm.exe,输入你的序列号,然后回车,如果结果显示“success.”表示成功,其他为失败。
源码:
#include <iostream>
#pragma comment(linker, "/BASE:0x00700000")
const char keydict[]=``"0123456789abcdefghijklmnopqrstuvwxyz"``;
int maze_data[3][9][10] = {``//不可分解为墙,可分解为路;
{
{11278, 4882,32580,19499,2406,7698,4707,6184,12705,21166},
{7622, 16409, 15753,24909,6730,14884,21510,3681,1624,3404},
{21539,18528,31112,8099,28763,17508,25583,16446,20683,5750},
{20786,26805,19000,28661,6299, 5899, 9988,8429,18744,18422},
{29970,20886,11132,19024,11860, 28606, 13618,31572,2749,10377},
{22208,12859,13976, 12751, 17242, 30202, 2603, 8203, 17901, 5695},
{9556,25275,13203, 10801,10582,12292,13956, 15854, 18348, 8807},
{25246, 7827, 31043, 26139, 32692,9562,15671,6148,27105,12588},
{14745,10559,12046,29754,279,25805,31862,23743,27312,1413}
},
// 第二层
{
{27900,15590,28587,3969,20764,9444,1925,23275,10615,3067},
{22008, 57, 10717, 18823, 4923, 24111, 32589, 25751, 25282, 14196},
{6182,1932,8379, 21619, 26806,10235,29473, 6926, 25216, 21730},
{20787, 25063, 12139, 23266, 6921, 25787, 1819, 25202, 17727, 8893},
{3432, 21161, 12566,6573,10486,5150,27408,12972,9108,13629},
{27200, 1687, 2062, 26755, 17047,5981,2874,17796,20408,21970},
{9618,24473,22918,23172, 29091, 14709, 1317, 15893, 2083, 4823},
{30959, 25451, 18202,21276,9208,14551,32356,6363,13390,22101},
{7273,3816,572,9672,1668,30573,2917,30805,24621,10110}
},
// 第三层
{
{24748,6277,28224,16108,5980,3371,20270,1605,27760,17789},
{23768,11026,284,31405,11870,14283,23800,23624, 25743, 14401},
{25412,32611,1474,3042,29050,29463,28954,17220, 793, 30062},
{12126,28402,9136,7893,23067,24575,29844,23628,32044, 11345},
{19428,20887,9092,25821,25321,20505,17534,7585,28851, 23299},
{6076,20180,15903,9976,10994,31588,17972,27097, 1882, 13387},
{10192,3228,14430,9366, 22069, 22442,17576,25263, 26087, 12932},
{31347,7375,9716,24013, 23774, 4251,30864,17871, 24559, 19131},
{38, 1149, 24865, 14914, 21785, 12975,8342,6375, 16769, 8114}
}
};
// 自定义绝对值函数
inline double custom_abs(``double val) {
return (val < 0) ? -val : val;
}
// 自定义平方根函数
double my_sqrt(``double x) {
// 处理边界值
if (x <= 0.0)``return 0.0;
if (x == 1.0)``return 1.0;
double guess = x / 2.0;``// 初始猜测值
double prev = 0.0;
const double eps = 1e-7;``// 精度阈值
int max_iter = 50;``// 最大迭代次数
for (``int i = 0; i < max_iter; ++i) {
prev = guess;
guess = 0.5 * (guess + x / guess);``// 牛顿迭代公式
// 计算相对误差
double diff = custom_abs(guess - prev);
if (diff < eps * custom_abs(guess)) {
break``;
}
}
return guess;
}
bool is_prime(``int num) {
if (num < 2)``return false``;
for (``int i = 2; i <= (``int``)my_sqrt((``double``)num); ++i) {
if (num % i == 0)``return false``;
}
return true``;
}
bool is_product_of_two_primes(``int n,``int``* p1 = NULL,``int``* p2 = NULL) {
if (n < 4)``return false``;
for (``int i = 2; i <= (``int``)my_sqrt((``double``)n); ++i) {
if (n % i == 0) {
int j = n / i;
if (is_prime(i) && is_prime(j)) {
if (p1) *p1 = i;
if (p2) *p2 = j;
return true``;
}
}
}
return false``;
}
bool checklic(``const char``*input)
{
if``(input==NULL ||``strlen``(input)==0)``return false``;
int nLenInput=``strlen``(input);
int nLenDict=``strlen``(keydict);
int x,y,z,x0,y0,z0;
x=y=z=0;
x0=y0=z0=0;
int step=0;
for``(``int i=0;i<nLenInput;i++)
{
char a=input[i];
int p=0;
for (;p<nLenDict;p++)
{
if``(keydict[p]==a)``break``;
}
if``(p>=nLenDict)``break``;
if``(p<12){
z=0;
}
else if``(p<24){
z=1;
}
else``{
z=2;
}
if``((i&1)==0)
{
y=p%12;
}
else
{
x=p%12;
step++;
// 起点终点特殊检查
if``(step==1 && maze_data[z][y][x]!=11278) {
return false``;
}
if``(i==nLenInput-1 && maze_data[z][y][x]!=8114) {
return false``;
}
// 路径点有效性检查
if``(step>1 && i<nLenInput) {
int p1, p2;
bool decomposable = is_product_of_two_primes(maze_data[z][y][x], &p1, &p2);
if (``false == decomposable) {
return false``;
}
if``(p1<2 || p2<2)``return false``;
if``(p1==p2)``return false``;
}
// 连续性检查
if``(step>1) {
int dz =``abs``(z - z0);
int dy =``abs``(y - y0);
int dx =``abs``(x - x0);
if``(dz+dy+dx != 1) {
return false``;
}
}
x0=x;
y0=y;
z0=z;
//最后一步必须为8114
if``(i==nLenInput-1 && maze_data[z][y][x]==8114) {
return true``;
}
}
}
return false``;
}
int main() {
printf``(``"input your serial:\n"``);
char szInputStr[200]={0};
std::cin.getline(szInputStr,``sizeof``(szInputStr));
if (``strlen``(szInputStr) <= 112 )``// 输入不能超过112个字符
{
bool ret=checklic(szInputStr);
if``(ret) {
printf``(``"\nsuccess.\n"``);
}``else {
printf``(``"\nfail!\n"``);
}
}
else
{
printf``(``"\nTry again...\n"``);
}
getchar``();
return 0;
}
writeup:
此题是一个三维迷宫的题目,不过对迷宫的路和墙做了加噪干扰,不能直观的看出来,需要对迷宫每个坐标上的整数做质数分解来还原路和墙,同时也对主逻辑函数的一小段代码做了拆分,使程序在IDA7.0~IDA9.1版本不能直接还原出完整的函数代码(其他版本没试过),需要手工修改还原,大概的求解过程如下:
-
将主逻辑函数的代码进行还原,方便在IDA里分析过程(在x86dbg里查看也可以,就是只能看汇编代码);
-
利用程序里的质数分解函数将3X9X10的迷宫还原成路和墙(比如:00表示墙,11表示路),这样可以比较直观的解出迷宫的路线,即从{0,0,0}到{2,8,9}的通行路线坐标序列;
-
3将路线坐标映射到字典字符,即得出要求解的序列号。
本题主要考查的是对三维数组映射到三维迷宫的空间想象力,还有一点就是对ret跳转的理解。
二、
赛题解析
解法1:
AI解题思路
该思路由论坛会员ID:【mb_czamoutp】提供
(1)去花
把栈魔法的跳转 patch 成跳到另一个地方就能让 F5 吐出比较正常的逻辑
(2)AI启动
我:已知unsigned char dword_703020[] = {…};
分析这个crackme的函数:char __usercall sub_701280@
给了一个函数之后 GPT-5 已经猜到个八九不离十,并且这里已经发现多解的可能了:
GPT:
总结
sub_701280 实现了一个 迷宫行走验证器:
输入字符串 → 映射为 base36 数组(可能带 leetspeak 容错)。
每个字符变成 3D 坐标 (layer,row,column)。
整个输入必须从起点格子(值=11278)开始,到终点格子(值=8114)结束。
相邻字符必须对应相邻格子(曼哈顿距离=1)。
每步还会通过 sub_7011C0 进一步检查格子属性(额外约束)。
返回 1 → 输入是合法路径。
返回 0 → 输入非法。
接下来可以做的事
要完全解出正确的 key(flag),需要:
确认 byte_7020F8 … byte_7020FD 的真实内容(决定输入字符集)。
理解 sub_7011C0 返回的 (v20,v21) 是什么。
把 dword_703020 解读为一个 3D 迷宫地图(每个格子存着一个编号/属性)。
之后我提供了:
我:007020F8和char __cdecl sub_7011C0(int a1, int *a2, int *a3) {}
然后 GPT-5 的思路也完全正确:
最后推 GPT 一把:
输入就是未经任何处理传入这个函数的。按已知的东西先求解一次
然后就是一分钟的 Agent 操作,直接给出flag:
已思考 1m 27s
计算32位整数数组元素数量 (272, [11278, 4882, 32580, 19499, 2406, 7698, 4707, 6184, 12705, 21166], [24865, 14914, 21785, 12975, 8342, 6375, 16769, 8114, 0, 0])
查找经过相邻单元格的路径 ((0, 0, 0), (2, 8, 9))
实现素数判定与半素数检测 (True, 2, 4057)
验证有效的半素数 True
计算BFS路径与邻居有效性 (56, [(0, 0, 0), (0, 0, 1), (0, 1, 1), (1, 1, 1), (1, 1, 2)], [(2, 5, 8), (2, 6, 8), (2, 7, 8), (2, 8, 8), (2, 8, 9)])
映射路径到base36字符对 崩溃了
校验路径字符映射有效性 (112, ‘0001111d1e1f2f3f3e3d’, ‘2w2x3x4x5x5w6w7w8w8x’)
打印完整字符串
0001111d1e1f2f3f3e3d4d5d5e5f53637372717d7c8c8o8p8q8r8s7s6s6g6h6i6j6757565545353h3i3j2j1j1k1w2w2x3x4x5x5w6w7w8w8x
习惯了 GPT 幻觉的笔者很惊讶地发现完整字符串就是可行解之一,并且GPT还给出了多解的说明:
直接让 GPT 生成两个变种也完全没问题:
c0c1d1dddedfeffffefdgdhdhehfh3i3j3j2j1jdjckckokpkqkrksjsisigihiiiji7h7h6h5g5f5fhfifjejdjdkdwewexfxgxhxhwiwjwkwkx
o0o1p1pdpepfqfrfrerdsdtdtetft3u3v3v2v1vdvcwcwowpwqwrwsvsusuguhuiuju7t7t6t5s5r5rhrirjqjpjpkpwqwqxrxsxtxtwuwvwwwwx
#
(3)后记
笔者在第一题题解中讨论了许多 GPT 逆向的话题,这里就不再赘述,但如今笔者愈加相信对于中等难度以下的逆向,SOTA LLM 很有可能会比人类选手做的更快且更准确。
另外笔者也测试了 MCP 的效果,但使用 GPT-5 mini 作为 LLM 的 MCP 效果并不理想,虽然分析正确,但并没能找到合理的搜索方法走出迷宫。可能和笔者给的提示词有关,但正文中使用的旗舰 GPT-5 在无任何技巧提示的情况下就完美解出了本题,或许模型的差异也对自动逆向效果有显著影响吧。
解法2:
传统解题思路
该思路由论坛会员ID:【HHHso】提供
该题定义了unsigned int dwtbl[3][9][10]三个有限位面穿行特征限制,需要找到从起始坐标到终点坐标之间有效穿梭路径;serial中每两个字符(ch,cl)在字符集cs = ‘0123456789abcdefghijklmnopqrstuvwxyz’中的索引计算得到位面内坐标(h,l)=(cs.index(ch)%12,cs.index(cl)%12),其由于(s,h,l)坐标中s坐标计算cs.index(cl)/12与h的原值cs.index(ch)无关,导致h的原码字符ch可以脱离l的原码字符cl所在字符段(cs每12字节长构成一个字符段)导致多解。
Step 1
通过windows系统的wsl linux子系统file测试目标,32位应用。
| | |
| — | — |
| 1 2 | file /mnt/d/pediyctf25/ido/ctf02/yegu_cm``.exe /mnt/d/pediyctf25/ido/ctf02/yegu_cm``.exe: PE32 executable (console) Intel 80386,``for MS Windows |
Step 2
通过readme.txt文件得到敏感字符串【success.】
Step 3
用IDA加载测试目标,执行下述脚本定位到【success.】位置
def loadfbs(``file``):
with``open``(``file``,``'rb'``) as fin:
return fin.read()
import idc
import idaapi
import pefile
fp``= idaapi.get_input_file_path()
pe``= pefile.PE(fp)
fbs``= loadfbs(fp)
fbs.count(b``'success.'``)``# ==> 1
dbase``= idaapi.get_imagebase()
idc.jumpto(dbase``+``pe.get_rva_from_offset(fbs.index(b``'success.'``)))
Step 4
通过对【success.】的交叉引用,定位到核心业务逻辑,如下,其中方框圈起的汇编代码,为strlen的实现。
伪码如下,我们随后进入【sub_701280】关于其校验业务逻辑
Step 5
【sub_701280】函数开始做了简单的混淆,根进发现,其实际就是strlen功能;同时发现我们可以刚好把strlen代码进行回填,清除混淆。
Step 6
执行下述IDAPython脚本进行混淆清除,实际就是将下述绿色圈起的汇编代码【mov eax,esi】(b’\x89\xf0′)规整到0x701293处,并自动衔接后面的【sub eax,edx】
| | |
| — | — |
| 1 | ida_bytes.patch_bytes(0x701293,b``'\x89\xf0'``+ida_bytes.get_bytes(0x00701EEB,10)) |
通过重新code分析,F5得到校验业务逻辑的伪码,如下:
Step 7
作者想要的基本校验业务逻辑如下(但实际存在漏洞,导致bug多解)
(``1``)假定字符集cs``=``{s0,s1,s2},则cs由s0,s1,s2三个``12``字节长串构成,如下
cs``= '0123456789abcdefghijklmnopqrstuvwxyz'
s0``= '0123456789ab' # 0
s1``= 'cdefghijklmn' # 1
s2``= 'opqrstuvwxyz' # 2
(``2``)一个``270``的字组 dwtbl[``3``][``9``][``10``],位于``0x703020
(``3``)serail中每两个字符(ch,cl)构成一个三维坐标(s,h,l),会确定一个字值dwv``= dwtbl[s][h][l];
h``= cs.index(ch)``%``12
l``= cs.index(cl)``%``12
s``= cs.index(cl)``/``/``12 # 这就导致h可以于l不同段(s0,s1,s2),作者期望h和l同段。
(``4``)其要求第一个字值为``0x2C0E``,最后一个字值``0x1FB2``,其他字值满足以下条件:
(``4.1``)rt,a,b``= sub_7011C0(dwtbl[s][h][l]),其中rt指示函数是否成功,a,b为根据输入值返回两个值。
(``4.2``)要求 rt!``=``0 && a>``=``2 && b>``=``2 & a!``=``b
(``5``)同时要求相邻两个坐标的s,h,l只能有一个相差``1``,其他两个不变。
总言之,``0x703020``处定义了dwtbl[``3``][``9``][``10``]一个三位面的地图,指明了起点(``0``,``0``,``0``)和终点(``2``,``8``,``9``),
以及同位面中dwtbl[s][``9``][``10``]行列相邻之间(相同的s)、相邻位面之间[``3``][h][l](相同的h和l)可以通过sub_7011C0标定是否可通行,
需要在位面中,和位面之间找到穿梭路径;
通过下述脚本,可得到各位面字表,如图:
import ida_bytes
import struct
dwtbl_ea``= 0x703020
dwbs``= ida_bytes.get_bytes(dwtbl_ea,``3``*``9``*``10``*``4``)
dwtbl``= struct.unpack(``'270L'``,dwbs)
for s``in range``(``3``):
print``(f``"s[{s}]: # 位面 {s}"``)
for i,c``in enumerate``(dwtbl[s``*``90``:s``*``90``+``90``]):
print``(f``"0x{c:04X} "``,end``=``'')
if (i``+``1``)``%``10``=``=``0``:
print``(f``"\n {(i//10)+1} "``,end``=``'')
print``("")
其中dwtbl[0][0][0]=0x2C0E和dwtbl[2][8][9]=0x1FB2,就是我们的起、始坐标。
Step 8
如何获取三个位面各个坐标点是否可通行?这里我们直接调用原函数rt=sub_7011C0(dwtbl[s][h][l],&a,&b)获取270个坐标字dwtbl[s][h][l]对应的rt表、a表、b表;
(1)我们用xdbg加载测试目标,在0x70152b处下断点,实际位置随意,运行断下;
(2)通过在xdbg的``command``中输入【alloc 0x1000】分配内存,这里执行后提示返回0x670000基址;
(3)在0x70152b处按空格快捷键进行汇编输入,输入以下汇编代码,其中rt.tbl,a.tbl,b.tbl地址要根据(2)返回基址进行调节
xor edi,edi
mov esi,edi
shl esi,2
lea edx,dword ptr ds:[esi+0x670500]
push edx
lea edx,dword ptr ds:[esi+0x670000]
push edx
mov edx,dword ptr ds:[esi+0x703020]
push edx
call 0x7011C0
add esp,0x0C
mov byte ptr ds:[edi+0x670A00],al
inc edi
cmp edi,0x10E
jl 0x70152D
xor eax,eax
(4)在最后的xor eax,eax处下断点,执行断下;
(5)通过在xdbg的``command``中输入【savedata D:\pediyctf25\ido\ctf02\mret.bin,0x670000,0x1000】dump出结果
Step 9
通过下述python脚本输出输出文件,可以得到三个位面的可穿行图,如下:
def loadfbs(``file``):
with``open``(``file``,``'rb'``) as fin:
return fin.read()
import struct
fbs``= loadfbs(r``'D:\pediyctf25\ido\ctf02\mret.bin'``)
atbl``= struct.unpack(``'270L'``,fbs[:``270``*``4``])
btbl``= struct.unpack(``'270L'``,fbs[``0x500``:``0x500``+``270``*``4``])
rtbl``= struct.unpack(``'270B'``,fbs[``0xA00``:``0xA00``+``270``])
psx``= [(``'x' if (r!``=``0 and a>``=``2 and b>``=``2 and a!``=``b)``else '0'``)``for a,b,r``in zip``(atbl,btbl,rtbl)]
for s``in range``(``3``):
print``(f``"s[{s}]: # 位面 {s}"``)
for i,c``in enumerate``(psx[s``*``90``:s``*``90``+``90``]):
print``(f``"{i:02d}.{c} "``,end``=``'')
if (i``+``1``)``%``10``=``=``0``:
print``("")
print``("")
其中【x】标记的即是可通行坐标,x前的为(h,l)位面内坐标,于位面序号组成有效的(s,h,l)坐标
Step 10
其中位面内和位面之间从起始点到终点的唯一穿行路径如下,蓝色为位面内穿梭,黄色为相邻位面之间穿梭。
即我们可以得到作者想要的穿梭路径如下
Step 11
位面0的h和l不需要转码,我们将位面1和位面2的进行转码,如下:
s0``= '0123456789ab' # 0
s1``= 'cdefghijklmn' # 1
s2``= 'opqrstuvwxyz' # 2
print``('``'.join([s1[int(c)] for c in '``11 12 13 23 33 32 31 41 51 52 53``'.replace(' ','``')]))
print``('``'.join([s1[int(c)] for c in '``71 70 80``'.replace(' ','``')]))
print``('``'.join([s1[int(c)] for c in '``64 65 66 67``'.replace(' ','``')]))
print``('``'.join([s1[int(c)] for c in '``35 36 37 27 17 18``'.replace(' ','``')]))
print``('``'.join([s2[int(c)] for c in '``80 81 82 83 84 74 64``'.replace(' ','``')]))
print``('``'.join([s2[int(c)] for c in '``18 28 29 39 49 59 58 68 78 88 89``'.replace(' ','``')]))
dddedfeffffefdgdhdhehf
jdjckc
igihiiij
fhfifjejdjdk
wowpwqwrwsvsus
pwqwqxrxsxtxtwuwvwwwwx
于是得到:
'00 01 11 dddedfeffffefdgdhdhehf 53 63 73 72 71 jdjckc wowpwqwrwsvsus igihiiij 67 57 56 55 45 35 fhfifjejdjdk pwqwqxrxsxtxtwuwvwwwwx'``.replace(``' '``,'')
Out[``181``]:``'000111dddedfeffffefdgdhdhehf5363737271jdjckcwowpwqwrwsvsusigihiiij675756554535fhfifjejdjdkpwqwqxrxsxtxtwuwvwwwwx'
即可得到标准的serail为【000111dddedfeffffefdgdhdhehf5363737271jdjckcwowpwqwrwsvsusigihiiij675756554535fhfifjejdjdkpwqwqxrxsxtxtwuwvwwwwx】
Step 12
潜在多解缺陷,从前面的算法可知,(s,h,l)中的s=cs.index(cl)//12得到,这就导致h=cs.index(ch)//12的ch可以是其他字符段的值,如下我们在标准serial
(1)的基础上,将某个坐标的h=cs.index(ch)%12的ch到其他字符段字符,都会验证成果:
(1)000111dddedfeffffefdgdhdhehf5363737271jdjckcwowpwqwrwsvsusigihiiij675756554535fhfifjejdjdkpwqwqxrxsxtxtwuwvwwwwx
(2)0001111ddedfeffffefdgdhdhehf5363737271jdjckcwowpwqwrwsvsusigihiiij675756554535fhfifjejdjdkpwqwqxrxsxtxtwuwvwwwwx
(3)0001111ddedfeffffefdgdhdhehf5363737271jdjckcwowpwqwrwsvsusigihiiij675756554535fhfifjejdjdkpwqwqxrxsxtxtwuwvwww8x
1
扫码参赛
第三题《邪影显现》火热挑战中
关于KCTF
看雪CTF(简称KCTF)是圈内知名度最高的技术竞技,从原CrackMe攻防大赛中发展而来,采取线上PK的方式,规则设置严格周全,题目涵盖Windows、Android、iOS、Pwn、智能设备、Web等众多领域。
扫码进入2025 KCTF
主办方
支持单位
看雪CTF比赛分为两个阶段,所有论坛会员均可参与,第一阶段是防守篇,防守方根据比赛要求制作题目,根据题目被破解的时间排名,被破解时间长者胜出。第二阶段为攻击篇,攻击第一阶段的题目,根据攻击成功的时间与题目排名,破解时间短且破解题目数多者胜。既给了防守方足够的施展空间,也避免过度浪费攻击方的时间。从攻防两个角度看,都是个难得的竞技和学习机会。
看雪CTF比赛历史悠久、影响广泛。自2007年以来,看雪已经举办十多个比赛,与包括金山、360、腾讯、阿里等在内的各大公司共同合作举办赛事。比赛吸引了国内一大批安全人士的广泛关注,历年来CTF中人才辈出,汇聚了来自国内众多安全人才,高手对决,精彩异常,成为安全圈的一次比赛盛宴,突出了看雪论坛复合型人才多的优势,成为企业挑选人才的重要途径,在社会安全事业发展中产生了巨大的影响力。
- End –
球分享
球点赞
球在看
戳“阅读原文”一起来充电吧!
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:看雪学苑 2025 KCTF《2025 KCTF | 第二题《初窥门径》设计思路及解析》