-
-
[原创]buuctf-re
-
发表于: 2025-7-10 02:02 3190
-
查看主函数:
第一个判断函数sub_4006D6:
一串长度为10的数字,输入的数字在47<a1[i]<=52也就是在0~4之间
再看这一行
v4 = sub_400758(&v5, 0LL, 10LL);
这是递归函数
如果v5==32 是空格或者 v5==10是换行键或者所处理的长度大于输入的数字的长度10就返回0
且下面的逻辑是构建一棵二叉树,树的节点存储的是输入数据中的字符。先序遍历
再看这一行
sub_400807(v4, &v7);
这段代码的功能是中序遍历一棵二叉树,并将节点的值存储到输出数组中。
sub_400881(&v7);
最后关键的函数是sub_400917():
这里是检查数组是否满足某种“唯一性”条件
if ( *(&unk_601060 + 5 * i + j) == *(&unk_601060 + 5 * i + k) )
if ( *(&unk_601060 + 5 * j + i) == *(&unk_601060 + 5 * k + i) )
这段代码的作用是检查一个 5x5 的二维数组 unk_601060 是否满足“每行和每列都没有重复值”
我们可以看到原数字表的数

就可以猜到所需的数字了,相当于数独
1 4 x 2 3
3 0 x 1 x
0 x 2 3 x
x 3 x x 0
4 2 x x 1
得到密文是0421421430最后反向写出二叉树即可

根据先序遍历的二叉树中序遍历的顺序是7 → 3 → 8 → 1 → 9 → 4 → 0 → 5 → 2 → 6
总体逻辑:

写代码解决
这里用的linux远程调控
ida查看
是ELF文件发现有mprotect函数,这是一道SMC
需要在linux中远程运行,我们看到了sub_402219函数里面是
让后查看汇编代码,发现是这样的猜测这里是SMC加密的地方


输入测试用例12345678901234567890123456789012让后在循环结束之后的地方设置断点,进入函数 之后让后查看源码
分析逻辑,其中有一个一直被引用的数表byte_4023A0,shift+e查看数据,其16进制数表示正好和AES的S盒数据相同,而且我们输入的是32位,这里一次加密16位也符合AES加密逻辑,所以猜测v4是密钥,是unk_603170

我们继续动态调试找到密钥unk_603170

CB8D493521B47A4CC1AE7E62229266CE
和密文byte_6030A0

BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B

flag{924a9ab2163d390410d0a1f670}
下载之后是一个安装包,之后安装完查壳是c#和.net架构,使用dnspy工具

找和字符串 DECODE! 相关的代码 我们直接在所选文件中搜索即可

找到关键代码处,分析逻辑,C#语言也看不懂啊,ai跑一下
这段代码是一个C# Windows Forms应用程序的一部分,它定义了一个名为Form1的窗体类。这个窗体包含一个按钮、一个标签和一个图片框。下面是对代码中逻辑的分析:
总结来说,这段代码定义了一个简单的Windows Forms应用程序,其中包含一个按钮,当点击按钮时,会执行一系列编码和解码操作,最终将结果显示在标签上。这个过程涉及到位操作和异或加密,但具体的加密算法和目的需要更多的上下文信息来确定
所以猜测当点击按钮时生成一个标签,而这个标签就是我们要的flag,也就是lbl_title,动态调试一下查看结果
如果没有的话可以把一些东西都开开
调试 -> 选项 -> 有啥显示的可以打开

设置断点 -> 运行 -> 让后中断 -> 查看局部变量


因为最后的flag格式是和邮箱相关的,所以猜测是这一个
flag{3rmahg3rd.b0b.d0ge@flare-on.com}
是apk文件,jadx打开
虚拟机运行一下发现是射击类的游戏

apk游戏逆向关键处一般在
Assets/bin/data/managed/assembly-csharp.dll
我们直接解压,用ida打开,划到最后看到了flag

MRCTF{Unity_1S_Fun_233}
本帖未解决
57dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8V1y4e0e0V1^5J5x3o6p5&6i4K6u0r3j5i4u0@1K9h3y4D9k6g2)9J5c8X3c8W2N6r3q4A6L8s2y4Q4x3V1j5I4x3e0j5%4x3K6R3#2x3U0M7`.
2022年 firmware-mod-kit 配置方法 - Carykd - 博客园
下载之后是.bin文件,一般.bin文件是
可执行文件,(IDA Pro)
光盘镜像文件,(使用刻录工具(如 dd 或 cdrecord))
系统文件或驱动程序
和其他存储用户数据或配置信息的文件.
这里给出了提示是路由器固件dump文件

而学习了解到了Binwalk 是一款功能强大的开源工具,主要用于分析、逆向工程和提取固件映像文件。
如果 .bin 文件是一个固件文件(例如路由器、打印机或其他嵌入式设备的固件),Binwalk 是非常适用的。它可以扫描固件文件,识别其中的文件系统、压缩数据、加密特征等,并提取出文件系统中的文件或其他有用数据。
所以学习binwalk的使用对本题非常的重要
我直接在共享文件夹里面安装了
安装binwalk
提取文件
之后出现一个文件夹


我们需要查看120200.squashfs这是一个linux的压缩文件
我们需要firmware-mod-kit工具来进行解压。
注意:下载的时候不要放到windows和linux的共享文件中,否则会报错:
ln: 无法创建符号链接" ...... ": 不支持的操作
打开终端
我这里的make一直报错,要崩溃了,先放一放吧qwq
......................
安装后虚拟机文件中会有一个firmware-mod-kit文件
把文件放在firmware-mod-kit目录下进行解压:
将上面120200.squashfs复制到firmware-mod-kit中
在下面路径firmware-mod-kit -> squashfs -> tmp中:出现了backdoor,之后分析代码即可
打开是扫雷游戏,C#语言,使用dnspy打开,之后查看关键处,有一个GetKey的代码
这里的flag不容易直接获取,所以我们改游戏胜利条件
找到这个函数SquareRevealedCallbac,是一个回调函数
直接把下面的代码删除,然后保存运行

记住这几个8的位置,因为修改文件之后可能会 出错

直接重新下载文件点击对应位置即可

flag{Ch3aters_Alw4ys_W1n@flare-on.com}
ctf中迷宫题型解题脚本总结_ctf逆向题迷宫题-CSDN博客
打开来看是一道迷宫题目
分析之后,思路还是挺清晰的,其中看到了这种
就猜测是3维地图了,分析也能知道是3层
让后是,一层255个,大小是15*15
之后找地图

需要注意的是地图数据存储类型的原因,我们只要四位中的第一位
写代码找到正确的地图

找到地图了,可以手动解决,也可以尝试BFS,这里有多条路,不是唯一的但猜测是寻找最短路线,所以也就使用BFS而不是DFS了
因为这里是每一层,从3到4,所以可以当做是三个二维地图,这样代码写起来比较方便
unsigned __int64 __fastcall main(int a1, char **a2, char **a3){ __int64 v4; // [rsp+8h] [rbp-38h] __int64 v5; // [rsp+10h] [rbp-30h] BYREF __int16 v6; // [rsp+18h] [rbp-28h] __int64 v7; // [rsp+20h] [rbp-20h] BYREF __int16 v8; // [rsp+28h] [rbp-18h] char v9; // [rsp+2Ah] [rbp-16h] unsigned __int64 v10; // [rsp+38h] [rbp-8h] v10 = __readfsqword(0x28u); v5 = 0LL; v6 = 0; v7 = 0LL; v8 = 0; v9 = 0; __isoc99_scanf("%s", &v5); if ( sub_4006D6(&v5) ) { v4 = sub_400758(&v5, 0LL, 10LL); sub_400807(v4, &v7); v9 = 0; sub_400881(&v7); if ( sub_400917() ) { puts("TQL!"); printf("flag{"); printf("%s", &v5); puts("}"); } else { puts("your are cxk!!"); } } return __readfsqword(0x28u) ^ v10;}unsigned __int64 __fastcall main(int a1, char **a2, char **a3){ __int64 v4; // [rsp+8h] [rbp-38h] __int64 v5; // [rsp+10h] [rbp-30h] BYREF __int16 v6; // [rsp+18h] [rbp-28h] __int64 v7; // [rsp+20h] [rbp-20h] BYREF __int16 v8; // [rsp+28h] [rbp-18h] char v9; // [rsp+2Ah] [rbp-16h] unsigned __int64 v10; // [rsp+38h] [rbp-8h] v10 = __readfsqword(0x28u); v5 = 0LL; v6 = 0; v7 = 0LL; v8 = 0; v9 = 0; __isoc99_scanf("%s", &v5); if ( sub_4006D6(&v5) ) { v4 = sub_400758(&v5, 0LL, 10LL); sub_400807(v4, &v7); v9 = 0; sub_400881(&v7); if ( sub_400917() ) { puts("TQL!"); printf("flag{"); printf("%s", &v5); puts("}"); } else { puts("your are cxk!!"); } } return __readfsqword(0x28u) ^ v10;}__int64 __fastcall sub_4006D6(const char *a1){ int i; // [rsp+1Ch] [rbp-4h] if ( strlen(a1) == 10 ) { for ( i = 0; i <= 9; ++i ) { if ( a1[i] > 52 || a1[i] <= 47 ) goto LABEL_2; } return 1LL; } else {LABEL_2: puts("Wrong!"); return 0LL; }}__int64 __fastcall sub_4006D6(const char *a1){ int i; // [rsp+1Ch] [rbp-4h] if ( strlen(a1) == 10 ) { for ( i = 0; i <= 9; ++i ) { if ( a1[i] > 52 || a1[i] <= 47 ) goto LABEL_2; } return 1LL; } else {LABEL_2: puts("Wrong!"); return 0LL; }}_QWORD *__fastcall sub_400758(__int64 a1, int a2, unsigned int a3){ char v5; // [rsp+1Fh] [rbp-11h] _QWORD *v6; // [rsp+28h] [rbp-8h] v5 = *(a2 + a1); if ( v5 == 32 || v5 == 10 || a2 >= a3 ) return 0LL; v6 = malloc(24uLL); *v6 = v5; v6[1] = sub_400758(a1, 2 * a2 + 1, a3); v6[2] = sub_400758(a1, 2 * (a2 + 1), a3); return v6;}_QWORD *__fastcall sub_400758(__int64 a1, int a2, unsigned int a3){ char v5; // [rsp+1Fh] [rbp-11h] _QWORD *v6; // [rsp+28h] [rbp-8h] v5 = *(a2 + a1); if ( v5 == 32 || v5 == 10 || a2 >= a3 ) return 0LL; v6 = malloc(24uLL); *v6 = v5; v6[1] = sub_400758(a1, 2 * a2 + 1, a3); v6[2] = sub_400758(a1, 2 * (a2 + 1), a3); return v6;}__int64 __fastcall sub_400807(__int64 a1, __int64 a2){ __int64 result; // rax result = a1; if ( a1 ) { sub_400807(*(a1 + 8), a2); *(a2 + dword_601080++) = *a1; return sub_400807(*(a1 + 16), a2); } return result;}__int64 __fastcall sub_400807(__int64 a1, __int64 a2){ __int64 result; // rax result = a1; if ( a1 ) { sub_400807(*(a1 + 8), a2); *(a2 + dword_601080++) = *a1; return sub_400807(*(a1 + 16), a2); } return result;}__int64 __fastcall sub_400881(char *a1){ __int64 result; // rax byte_601062 = *a1; byte_601067 = a1[1]; byte_601069 = a1[2]; byte_60106B = a1[3]; byte_60106E = a1[4]; byte_60106F = a1[5]; byte_601071 = a1[6]; byte_601072 = a1[7]; byte_601076 = a1[8]; result = a1[9]; byte_601077 = a1[9]; return result;}__int64 __fastcall sub_400881(char *a1){ __int64 result; // rax byte_601062 = *a1; byte_601067 = a1[1]; byte_601069 = a1[2]; byte_60106B = a1[3]; byte_60106E = a1[4]; byte_60106F = a1[5]; byte_601071 = a1[6]; byte_601072 = a1[7]; byte_601076 = a1[8]; result = a1[9]; byte_601077 = a1[9]; return result;}__int64 sub_400917(){ unsigned int v1; // [rsp+0h] [rbp-10h] int i; // [rsp+4h] [rbp-Ch] int j; // [rsp+8h] [rbp-8h] int k; // [rsp+Ch] [rbp-4h] v1 = 1; for ( i = 0; i <= 4; ++i ) { for ( j = 0; j <= 4; ++j ) { for ( k = j + 1; k <= 4; ++k ) { if ( *(&unk_601060 + 5 * i + j) == *(&unk_601060 + 5 * i + k) ) v1 = 0; if ( *(&unk_601060 + 5 * j + i) == *(&unk_601060 + 5 * k + i) ) v1 = 0; } } } return v1;}__int64 sub_400917(){ unsigned int v1; // [rsp+0h] [rbp-10h] int i; // [rsp+4h] [rbp-Ch] int j; // [rsp+8h] [rbp-8h] int k; // [rsp+Ch] [rbp-4h] v1 = 1; for ( i = 0; i <= 4; ++i ) { for ( j = 0; j <= 4; ++j ) { for ( k = j + 1; k <= 4; ++k ) { if ( *(&unk_601060 + 5 * i + j) == *(&unk_601060 + 5 * i + k) ) v1 = 0; if ( *(&unk_601060 + 5 * j + i) == *(&unk_601060 + 5 * k + i) ) v1 = 0; } } } return v1;}#include<stdio.h>int main(){ int a[]={7,3,8,1,9,4,0,5,2,6}; int b[]={0,4,2,1,4,2,1,4,3,0}; int flag[10]; for(int i=0;i<10;i++){ flag[a[i]]=b[i]; } for(int i=0;i<10;i++){ printf("%d",flag[i]);//1134240024 } return 0; }//0421421430//7 → 3 → 8 → 1 → 9 → 4 → 0 → 5 → 2 → 6///flag{1134240024}#include<stdio.h>int main(){ int a[]={7,3,8,1,9,4,0,5,2,6}; int b[]={0,4,2,1,4,2,1,4,3,0}; int flag[10]; for(int i=0;i<10;i++){ flag[a[i]]=b[i]; } for(int i=0;i<10;i++){ printf("%d",flag[i]);//1134240024 } return 0; }//0421421430//7 → 3 → 8 → 1 → 9 → 4 → 0 → 5 → 2 → 6///flag{1134240024}void __fastcall __noreturn main(int a1, char **a2, char **a3){ int i; // [rsp+8h] [rbp-48h] char s[40]; // [rsp+20h] [rbp-30h] BYREF unsigned __int64 v5; // [rsp+48h] [rbp-8h] v5 = __readfsqword(0x28u); __isoc99_scanf("%39s", s); if ( (unsigned int)strlen(s) != 32 ) // 长32位 { puts("Wrong!"); exit(0); } mprotect(&dword_400000, 0xF000uLL, 7); for ( i = 0; i <= 223; ++i ) *((_BYTE *)sub_402219 + i) ^= 0x99u; sub_40207B(&unk_603170); sub_402219(s);}void __fastcall __noreturn main(int a1, char **a2, char **a3){ int i; // [rsp+8h] [rbp-48h] char s[40]; // [rsp+20h] [rbp-30h] BYREF unsigned __int64 v5; // [rsp+48h] [rbp-8h] v5 = __readfsqword(0x28u); __isoc99_scanf("%39s", s); if ( (unsigned int)strlen(s) != 32 ) // 长32位 { puts("Wrong!"); exit(0); } mprotect(&dword_400000, 0xF000uLL, 7); for ( i = 0; i <= 223; ++i ) *((_BYTE *)sub_402219 + i) ^= 0x99u; sub_40207B(&unk_603170); sub_402219(s);}void __noreturn sub_402219(){ __debugbreak();}void __noreturn sub_402219(){ __debugbreak();}__int64 __fastcall sub_40221A(__int64 a1){ unsigned int v2; // [rsp+18h] [rbp-D8h] int i; // [rsp+1Ch] [rbp-D4h] char v4[200]; // [rsp+20h] [rbp-D0h] BYREF unsigned __int64 v5; // [rsp+E8h] [rbp-8h] v5 = __readfsqword(0x28u); sub_400A71(v4, &unk_603170); sub_40196E(v4, a1); sub_40196E(v4, a1 + 16); v2 = 1; for ( i = 0; i <= 31; ++i ) { if ( *(_BYTE *)(i + a1) != byte_6030A0[i] ) v2 = 0; } return v2;}__int64 __fastcall sub_40221A(__int64 a1){ unsigned int v2; // [rsp+18h] [rbp-D8h] int i; // [rsp+1Ch] [rbp-D4h] char v4[200]; // [rsp+20h] [rbp-D0h] BYREF unsigned __int64 v5; // [rsp+E8h] [rbp-8h] v5 = __readfsqword(0x28u); sub_400A71(v4, &unk_603170); sub_40196E(v4, a1); sub_40196E(v4, a1 + 16); v2 = 1; for ( i = 0; i <= 31; ++i ) { if ( *(_BYTE *)(i + a1) != byte_6030A0[i] ) v2 = 0; } return v2;}sudo apt-get updatesudo apt install binwalksudo apt-get updatesudo apt install binwalkbinwalk -e firmware.binbinwalk -e firmware.bin# For Ubuntu 需要安装的依赖库文件 sudo apt updatesudo apt install python3-magicsudo apt-get install git build-essential zlib1g-dev liblzma-dev python3-magic autoconf python-is-python3sudo apt install git(没有的需要安装一下)#给予权限,如果需要的话sudo suchmod 777 firmware-mod-kit#也可以在操作前面加上 sudo #gitgit clone https://github.com/mirror/firmware-mod-kit.gitgit clone https://gitee.com/hilbertw/firmware-mod-kit.git# 进入源码目录 cd firmware-mod-kit/src #执行configure文件生成Makefile文件./configure#make编译生成可执行文件make# For Ubuntu 需要安装的依赖库文件 sudo apt updatesudo apt install python3-magicsudo apt-get install git build-essential zlib1g-dev liblzma-dev python3-magic autoconf python-is-python3sudo apt install git(没有的需要安装一下)#给予权限,如果需要的话sudo suchmod 777 firmware-mod-kit#也可以在操作前面加上 sudo #gitgit clone https://github.com/mirror/firmware-mod-kit.gitgit clone https://gitee.com/hilbertw/firmware-mod-kit.git# 进入源码目录 cd firmware-mod-kit/src #执行configure文件生成Makefile文件./configure#make编译生成可执行文件make./extract-firmware.sh 120200.squashfs./extract-firmware.sh 120200.squashfs// UltimateMinesweeper.MainForm// Token: 0x0600000D RID: 13 RVA: 0x000023E4 File Offset: 0x000005E4private string GetKey(List<uint> revealedCells){ revealedCells.Sort(); Random random = new Random(Convert.ToInt32(revealedCells[0] << 20 | revealedCells[1] << 10 | revealedCells[2])); byte[] array = new byte[32]; byte[] array2 = new byte[] { 245, 75, 65, 142, 68, 71, 100, 185, 74, 127, 62, 130, 231, 129, 254, 243, 28, 58, 103, 179, 60, 91, 195, 215, 102, 145, 154, 27, 57, 231, 241, 86 }; random.NextBytes(array); uint num = 0U; while ((ulong)num < (ulong)((long)array2.Length)) { byte[] array3 = array2; uint num2 = num; array3[(int)num2] = (array3[(int)num2] ^ array[(int)num]); num += 1U; } return Encoding.ASCII.GetString(array2);}// UltimateMinesweeper.MainForm// Token: 0x0600000D RID: 13 RVA: 0x000023E4 File Offset: 0x000005E4private string GetKey(List<uint> revealedCells){ revealedCells.Sort(); Random random = new Random(Convert.ToInt32(revealedCells[0] << 20 | revealedCells[1] << 10 | revealedCells[2])); byte[] array = new byte[32]; byte[] array2 = new byte[] { 245, 75, 65, 142, 68, 71, 100, 185, 74, 127, 62, 130, 231, 129, 254, 243, 28, 58, 103, 179, 60, 91, 195, 215, 102, 145, 154, 27, 57, 231, 241, 86 }; random.NextBytes(array); uint num = 0U; while ((ulong)num < (ulong)((long)array2.Length)) { byte[] array3 = array2; uint num2 = num; array3[(int)num2] = (array3[(int)num2] ^ array[(int)num]); num += 1U; } return Encoding.ASCII.GetString(array2);}// UltimateMinesweeper.MainForm// Token: 0x0600000C RID: 12 RVA: 0x00002348 File Offset: 0x00000548private void SquareRevealedCallback(uint column, uint row){ if (this.MineField.BombRevealed) { this.stopwatch.Stop(); Application.DoEvents(); Thread.Sleep(1000); new FailurePopup().ShowDialog(); Application.Exit(); } this.RevealedCells.Add(row * MainForm.VALLOC_NODE_LIMIT + column); if (this.MineField.TotalUnrevealedEmptySquares == 0) { this.stopwatch.Stop(); Application.DoEvents(); Thread.Sleep(1000); new SuccessPopup(this.GetKey(this.RevealedCells)).ShowDialog(); Application.Exit(); }}// UltimateMinesweeper.MainForm// Token: 0x0600000C RID: 12 RVA: 0x00002348 File Offset: 0x00000548private void SquareRevealedCallback(uint column, uint row){ if (this.MineField.BombRevealed) { this.stopwatch.Stop(); Application.DoEvents(); Thread.Sleep(1000); new FailurePopup().ShowDialog(); Application.Exit(); } this.RevealedCells.Add(row * MainForm.VALLOC_NODE_LIMIT + column); if (this.MineField.TotalUnrevealedEmptySquares == 0) { this.stopwatch.Stop(); Application.DoEvents(); Thread.Sleep(1000); new SuccessPopup(this.GetKey(this.RevealedCells)).ShowDialog(); Application.Exit(); }}new FailurePopup().ShowDialog(); Application.Exit();new FailurePopup().ShowDialog(); Application.Exit();__int64 __fastcall main(__int64 a1, char **a2, char **a3){ int v4; // [rsp+4h] [rbp-Ch] sub_11B4(); do v4 = sub_940(); while ( v4 != 1 && v4 != -1 ); return 0LL;}__int64 __fastcall main(__int64 a1, char **a2, char **a3){ int v4; // [rsp+4h] [rbp-Ch] sub_11B4(); do v4 = sub_940(); while ( v4 != 1 && v4 != -1 ); return 0LL;}unsigned __int64 sub_11B4(){ unsigned __int64 v1; // [rsp+8h] [rbp-8h] v1 = __readfsqword(0x28u); a = 0; return __readfsqword(0x28u) ^ v1;}unsigned __int64 sub_11B4(){ unsigned __int64 v1; // [rsp+8h] [rbp-8h] v1 = __readfsqword(0x28u); a = 0; return __readfsqword(0x28u) ^ v1;}__int64 sub_940(){ int v0; // eax int v2; // [rsp+8h] [rbp-218h] int v3; // [rsp+Ch] [rbp-214h] char v4[520]; // [rsp+10h] [rbp-210h] BYREF unsigned __int64 v5; // [rsp+218h] [rbp-8h] v5 = __readfsqword(0x28u); v3 = 0; memset(v4, 0, 0x200uLL); _isoc99_scanf(&unk_1278, v4, v4); while ( 1 ) { do { v2 = 0; update(); // 初始是3,不能重复走 v0 = v4[v3]; if ( v0 == 'd' ) { v2 = right(); } else if ( v0 > 'd' ) { if ( v0 == 's' ) { v2 = down(); } else if ( v0 == 'w' ) { v2 = up(); } } else { if ( v0 == 27 ) // ESC return 0xFFFFFFFFLL; if ( v0 == 'a' ) v2 = left(); } ++v3; } while ( v2 != 1 ); if ( a == 2 ) break; ++a; } puts("success! the flag is flag{md5(your input)}"); return 1LL;}__int64 sub_940(){ int v0; // eax int v2; // [rsp+8h] [rbp-218h] int v3; // [rsp+Ch] [rbp-214h] char v4[520]; // [rsp+10h] [rbp-210h] BYREF unsigned __int64 v5; // [rsp+218h] [rbp-8h] v5 = __readfsqword(0x28u); v3 = 0; memset(v4, 0, 0x200uLL); _isoc99_scanf(&unk_1278, v4, v4); while ( 1 ) { do { v2 = 0; update(); // 初始是3,不能重复走 v0 = v4[v3]; if ( v0 == 'd' ) { v2 = right(); } else if ( v0 > 'd' ) { if ( v0 == 's' ) { v2 = down();[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
赞赏
- [原创]buuctf-re 3347
- [原创]buuctf-re 3191
- [原创]buuctf-re 3004