偶尔来点跨界挑战——DUTCTF试水(开发区科技文化节网安竞赛)
室友是学校网安社团的一位大佬,这次为了给他们办的比赛捧场(主要还是想尝试点不一样的东西)而来试试水。
不过,笔者希望大伙别对我这几个小时速成的水平有什么期待就是了,以下是笔者解出来的为数不多几个题的解题步骤:
MISC(杂项)
1. SignIn
题干只给了一串字符串(见下图),看着像是栅栏密码,用 CyberChef 试试:

设置Key = 4, Offset = 0可得:答案为 DUTCTF{W31c0mE_TO_2o2s_DuTCTf_DuTEr5!}
2. 特定低手
题干给了一张图片,要求找到图片右上角黑白建筑的邮政编码,属于典型的社工题————应该是这么叫吧(心虚)。

(出题人被木柜子入侵了(悲))
首先查了图像的 EXIF 信息,结果一无所获。
然后在 Google 上搜图,意外发现了这么一帖子(回憶是一行行無從剪接的風景🌃 (threads.com)):

可见这位台湾朋友也是木柜子爱好者,然后,这个帖子中的最后一张图是这样的:

这些画了红圈的元素与原图是相同的,并且,主要建筑物的位置也基本上一样,两张图很可能是同一个地方拍摄的(角度不同)。
那么,这张图跟木柜子会不会有关联?比如取景地/圣地巡礼之类的?
结果,在B站上一个MyGO圣地巡礼的帖子里(【BanG Dream】圣地巡礼(含mygo) - 哔哩哔哩 (bilibili.com)),发现了这个:

出现了这座天桥。
多次出现的,灯家楼下的人行桥。虽然找到了这个人行桥,但是没有找到灯家那个建筑物。回去翻推特才知道,那个建筑物在另一个位置,下次来再找找(懒)
位置:東京都豊島区目白2丁目4−10
这样就找到了这天桥的位置
Google 一下这个地址,打开三维街景图,发现了这座天桥。

回到题干,我们要找到那座黑白建筑物的邮政编码,也就是图下这个:

没法获取这座建筑物的信息,但是,它旁边的这座建筑物,其邮编为 171-0032,一般来说,一个街区的邮编都是一样的吧?

取数字部分,进行MD5编码:

答案为:DUTCTF{446c1394494c91256ab74ed3cdcb1eb0}
REVERSE(逆向)
1. signin
下载可执行程序(https://files.cnblogs.com/files/blogs/840593/signin_reverse.zip?t=1746202078&download=true),
通过 DIE 查壳后发现是一个X86-64可执行文件:

用IDA进行逆向,发现程序结构只有一个主函数就结束了:

按F5生成伪C语言代码:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[8]; // [rsp+0h] [rbp-80h] BYREF
__int64 v5; // [rsp+8h] [rbp-78h]
__int64 v6; // [rsp+10h] [rbp-70h]
__int64 v7; // [rsp+18h] [rbp-68h]
__int64 v8; // [rsp+20h] [rbp-60h]
__int64 v9; // [rsp+28h] [rbp-58h]
__int64 v10; // [rsp+30h] [rbp-50h]
__int64 v11; // [rsp+38h] [rbp-48h]
char s1[64]; // [rsp+40h] [rbp-40h] BYREF
*(_QWORD *)s = 0LL;
v5 = 0LL;
v6 = 0LL;
v7 = 0LL;
v8 = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
*(_DWORD *)&s[strlen(s)] = 5526852;
strcpy(&s[strlen(s)], "CTF{");
*(_DWORD *)&s[strlen(s)] = 7746418;
strcpy(&s[strlen(s)], "3R53_");
*(_DWORD *)&s[strlen(s)] = 6235185;
strcpy(&s[strlen(s)], "\\/");
strcpy(&s[strlen(s)], "3ry_");
strcpy(&s[strlen(s)], "f(_)");
strcpy(&s[strlen(s)], "n&ea");
*(_DWORD *)&s[strlen(s)] = 2193717;
*(_WORD *)&s[strlen(s)] = 125;
printf("Input the flag: ");
fgets(s1, 64, _bss_start);
s1[strcspn(s1, "\n")] = 0;
if ( !strcmp(s1, s) )
puts("Correct!");
else
puts("Wrong!");
return 0;
}
去掉其他一系列没用的东西,然后把一部分内容换成人话,就是:
int main(int argc, const char **argv)
{
char s[8];
char s1[64];
*(_QWORD *)s = 0LL;
strcpy(&s[strlen(s)], "DUT"); //5526852 -> (hex)54 55 44 -> (小端)44 55 54 -> (UTF8) DUT
//以下类似
strcpy(&s[strlen(s)], "CTF{");
strcpy(&s[strlen(s)], "r3v"); //7746418
strcpy(&s[strlen(s)], "3R53_");
strcpy(&s[strlen(s)], "1$_"); //6235185
strcpy(&s[strlen(s)], "\\/");
strcpy(&s[strlen(s)], "3ry_");
strcpy(&s[strlen(s)], "f(_)");
strcpy(&s[strlen(s)], "n&ea");
strcpy(&s[strlen(s)], "5y!"); //2193717
strcpy(&s[strlen(s)], "}"); //125
printf("Input the flag: ");
fgets(s1, 64, _bss_start);
s1[strcspn(s1, "\n")] = 0;
if ( !strcmp(s1, s) )
puts("Correct!");
else
puts("Wrong!");
return 0;
}
这里显然是往字符串s内按照顺序塞东西。
把源码换成输出字符串s,可得内容为:DUTCTF{r3v3R53_1$_\/3ry_f(_)n&ea5y!}
CRYPTO(密码学)
1. Signin
题干如下:
ciphertext: 52354976201766669118320630176887314071011255313891475177309220942626308982212207656434544882959155963535322671950878583826524168178944409579938839799964263156869607430342733103192161887476831655038675686355158926050329782714167002188689556206753594011414672752687969286190800625479272347359078146861058813575
e: 65537
n: 128695631920242750589686556821575285363077338716894598150505853922988731458730235702902751496167097055081015591831536126839547857423987907590407313564456519185448221625668476322936885010691918434072938135430858464606477495727174799865802582744611435244880867181739290162314813391707310015481379681575178925149
还是能看出来是RSA的,然而,在 Factordb 上查询公钥 N 的因数,结果 N 居然是质数!

既然无法分解质因数,那这里只能默认 φ(N) = N - 1, d = e^-1mod φ(N),设 c 为密文,m = pow(c, d, N) 即得明文。
from sympy import mod_inverse
N = 128695631920242750589686556821575285363077338716894598150505853922988731458730235702902751496167097055081015591831536126839547857423987907590407313564456519185448221625668476322936885010691918434072938135430858464606477495727174799865802582744611435244880867181739290162314813391707310015481379681575178925149
e = 65537
c = 52354976201766669118320630176887314071011255313891475177309220942626308982212207656434544882959155963535322671950878583826524168178944409579938839799964263156869607430342733103192161887476831655038675686355158926050329782714167002188689556206753594011414672752687969286190800625479272347359078146861058813575
phi = N - 1
d = mod_inverse(e, phi)
m = pow(c, d, N)
n = m.to_bytes((m.bit_length() + 7) // 8, 'big').decode() # 转化为字符串
print("明文 m =", n)
得到结果为:DUTCTF{N3veR_U5e_0n1y_On3_Pr1me!}
总结
怎么说呢,偶尔接触一些自己过去从未接触的领域还是挺有意思的,不过,笔者大概率以后不会去深入学习CTF相关的内容(笑)。
另外,拜笔者那基本等于零的Web水平所赐,Web类的题是一道也做不了,以后有机会还是得学一下......
笔者也要回大连了,又有活干了...

浙公网安备 33010602011771号