2024XYCTF-WP-酱菜三剑客
XYCTF-WP-酱菜三剑客
misc
1、game
拿到图片,拖进谷歌搜图
点击链接
https://papersplease.fandom.com/wiki/EZIC
所以flag为
XYCTF{Papers Please}
2、熊博士
小纸条拖进随波逐流
得到flag xyctf{liu_ye_mei_you_xiao_jj}
再改成大写
得到最终flag
xyctf{LIU_YE_MEI_YOU_XIAO_JJ}
(好狠毒-_-)
3、真>签到
拖进010直接看到flag
所以flag为
XYCTF{59bd0e77d13c_1406b23219e_f91cf3a_153e8ea4_77508ba}
4、签到
没啥好讲的,就记得好像关注一下公众号就出来了
5、Osint1
拖进百度识图,找到小红书博主的回复
评论区得到flag
xyctf{江苏省|南通市|滨海东路|黄海}
6、EZ_Base1024*2
上网找了Base2048的解码网站,解码出来就是flag
flag
XYCTF{84ca3a6e-3508-4e34-a5e0-7d0f03084181}
7、ez_隐写
先看hint,拖入010发现这个高度不对劲,逐步修改高度从1000-3000另存为,然后在3000的图片下面发现提示
所以压缩包的解压密码就是XYCTF的开赛日期20240401
解压得到图片WATERMARK
猜测可能是用WATERMARK进行的隐写
拖进WARTERMARK一看,得到flag
XYCTF{159-WSX-IJN-852}
8、美妙的歌声(未解出)
wave拖进Audacity看频谱图,得到一个像flag的东西
但是包装为XYCTF{XYCTF_1s_w3ll}或者是flag{XYCTF_1s_w3ll}
提交上去都是不对的
9、Osint2(未解出)
图片信息有:
出题人在2024年3月26日15:10分在洛阳龙门站坐了开往泸州的高铁
去查了符合时间的高铁
查了班次说是到洛阳龙门站的时候车号是G3293
于是构造flag为
xyctf{G3293|中国河南省|洛阳龙门古镇}
但提交上去错误(为什么第一个空里面要填6个字符呢_)
10、Ez_osint(未解出)
上网查了这段话发现只有知乎的一个专栏有,不知道这个邮件是藏了个啥东西
(怎么还有在ctf题目里面杀单身狗的啊-_-)
11、彩蛋?(未解出)
在比赛须知里面找到一段
**and I think you know : **130131103124106173164150151163137141137
丢进随波逐流里面得到第一部分
8进制转字符: XYCTF{this_a_
后面的几部分就没找出来了-_-
12、疯狂大杂烩!九转功成(未解出)
解压密码是xyctf开始日期20240401
第一层
hint放进随波逐流得到
天书(曰)解码: First_layer_simple
解压得到图片,拖进010修改高度,在图片尾部得到第一部分的flag
XYCTF{T3e_c0mb1nation_
第二层
hint拖进随波逐流得到解压密码
BubbleBabble解码: The_second_layer_is_also_simple
解压得到的图片LSB隐写了Base64编码:
解码得到第二部分的flag:flag2:0f_crypt0_and_
第三层
随波逐流224查到hint对应的是circle编码
**解码得到 **
U K I J H G M
I N H G V T J
W K X B H J I
H D I G C J U
H K Y I I
Crypto
1、Sign1n[签到]和Sign1n_Revenge
先用gpt对代码注释了一下:
这段代码似乎在以一种有些复杂的方式操纵一个标志值。让我们逐步解释:
**导入库**:
1
2
3from Crypto.Util.number import *
from tqdm import *
import gmpy2这里导入了来自Crypto.Util.number、tqdm和gmpy2库的必要函数。
**标志初始化**:
1
2flag = b'XYCTF{uuid}'
flag = bytes_to_long(flag)将标志初始化为字节串b'XYCTF{uuid}',然后使用Crypto库中的bytes_to_long()函数将其转换为长整数。
**位泄漏**:
1
2
3
4
5leak = bin(int(flag))
while 1:
leak += "0"
if len(leak) == 514:
break该代码将标志整数转换为二进制字符串,并通过附加"0"扩展它,直到其达到514位的长度为止。
**位交换函数**:
1
2
3
4
5
6
7
8
9
10def swap_bits(input_str):
input_list = list(input_str[2:])
length = len(input_list)
for i in range(length // 2):
temp = input_list[i]
input_list[i] = input_list[length - 1 - i]
input_list[length - 1 - i] = temp
return ''.join(input_list)此函数接受一个二进制字符串作为输入,交换其中的位,并返回结果。
这个函数的目的是交换输入的二进制字符串中的位。现在让我逐行解释它:
input_list = list(input_str[2:]):将输入字符串转换为列表,起始索引从第二位开始,这是因为在输入字符串中,前两个字符是0b表示二进制的前缀。
length = len(input_list):获取输入列表的长度,以便后续迭代使用。
for i in range(length // 2)::迭代处理列表的前一半元素。这是因为在交换位的过程中,我们只需要交换前一半与后一半的位。
temp = input_list[i]:将当前位置的元素保存在临时变量temp中,以便稍后使用。
input_list[i] = input_list[length - 1 - i]:将当前位置的元素替换为与之对称的对应元素。例如,如果当前位置为i,则与之对称的位置为length - 1 - i。
input_list[length - 1 - i] = temp:将之前保存的临时变量temp的值赋给对称位置上的元素,完成交换。
return ''.join(input_list):将交换后的列表转换回字符串形式,并返回交换后的结果。
这样,swap_bits函数会返回输入字符串中位的顺序被颠倒的结果。
**位操作**:
1
2
3input_str = leak
result = swap_bits(input_str)
a = result在这里,将leak(标志的扩展二进制表示)通过swap_bits()函数,并将结果存储在a中。
**自定义加法函数**:
1
2
3
4
5
6
7
8
9def custom_add(input_str):
input_list = list(input_str)
length = len(input_list)
for i in range(length):
input_list[i] = str((int(input_list[i]) + i + 1) % 10)
result = ''.join(input_list)
return result此函数接受一个数字字符串作为输入,对每个数字加上其索引位置(加一),取结果模10,并返回新的字符串。
这个函数的目的是对输入的数字字符串进行加法操作。现在让我逐行解释它:
input_list = list(input_str):将输入的字符串转换为列表,这样我们可以逐个访问其中的每个数字。
length = len(input_list):获取输入列表的长度,以便后续迭代使用。
for i in range(length)::对列表中的每个元素进行迭代,即对输入的每个数字进行操作。
input_list[i] = str((int(input_list[i]) + i + 1) % 10):将当前数字字符串转换为整数,并加上当前索引i以及额外的1。然后取结果对10的模,并将其转换回字符串形式,更新到输入列表中的当前位置。
result = ''.join(input_list):将操作后的列表重新组合成一个字符串。
return result:返回加法操作后的结果字符串。
这样,custom_add函数会对输入的数字字符串进行自定义的加法操作,其中每个数字都会加上它的索引值再加1,并且结果会取模10以确保结果在0到9之间。
**位操作(第二部分)**:
1
2
3input_str = a
result = custom_add(input_str)
b = result将修改后的二进制字符串a通过custom_add()函数,并将结果存储在b中。
**打印结果**:
1
print(b)
打印最终结果(b)。
最终输出是一长串数字,看起来经历了某种操作,可能是加密或混淆。这段代码主要展示了对标志的位操作技术,可能作为密码挑战的一部分。****
然后用gpt写了一个解密函数:
1 | from Crypto.Util.number import * |
就可以得到两道题的flag
flag{8bb42495-c087-40d6-b854-0b1ae37e29e8}
XYCTF{1514ee1e-0398-45aa-8cf6-6e2efd0e8b56}
2、happy_to_solve1
抄网上流出的wp
题目给了n,c,e的值,要得到flag就得先解m的值。又因为m = pow(c, d, n), 且给了e值,所以利用p,q的生成规则求phi_n的值成为了问题的关键!
观察p, q生成的规则,发现p是随机取的512位的素数;
sympy.nextprime() 函数接受一个整数作为参数,并返回大于该整数的下一个素数;
1 << 512 是一个位运算,表示将1左移512位,即得到一个只有第513位为1的数,其他位都为0的数;
(1 << 512) - 1 是将上述结果减去1,得到一个二进制表示全为1的512位数;
所以q的结果就是p与512位的1进行异或的结果,再进行nextprime。
因为phi_n = n - (p + q) + 1 ,且n位数与全1按位异或等于取反,原码 + 反码 = 2 ** n - 1
我们先不计q在nextprime函数后的差值,所以p + q = 2 ** 512 - 1
又因为素数性质(除2之外都是奇数),因此,p + q = 2 ** 512 - 1 + t
所以,爆破!这里的t从1开始,每次爆完t + 2,满足奇数条件,直到有符合的怕p + q的值便可得到flag
1 | import gmpy2 |
最终flag
XYCTF{3f22f4efe3bbbc71bbcc999a0a622a1a23303cdc}
WEB
1、warm up
level1主要考phpmd5绕过和动态变量的变量覆盖
构造的payload为
http://localhost:9733/?val1=QNKCDZO&val2=s1091221200a&md5=0e215962017&XYCTF=QNKCDZO&XY=QNKCDZO
得到level2的地址
LLeeevvveeelll222.php
level2第一关先是post一个数组实现数组绕过
post a[]=1
第二关是preg_match命令执行漏洞
构造payload为
/LLeeevvveeelll222.php?a=/(.*)/e&b=system('cat /flag');
获得flag
XYCTF{e552eaa1-8e7f-4d76-9e22-1505d2a45295}
2、ezhttp
查看源代码可知密码藏起来了
于是猜是不是会在robots.txt里面
访问得到
再访问得到
username: XYCTF
password: @JOILha!wuigqi123$
拿着这两个去登录
发现出来这个
burp抓包,修改Referer为
yuanshen.com
发送得到提示
你用的不是XYCTF的浏览器
修改UA为XYCTF得到
非本地用户禁止访问!
添加XFF:127.0.0.1,结果
xff 打咩!!!
换成 Client-IP:127.0.0.1
得到
不是从 ymzx.qq.com 代理来的我不玩
构造代理
Via: ymzx.qq.com
,得到
有点饿,想吃点XYCTF的小饼干
于是修改cookie,Cookie: XYCTF
最终得到flag
XYCTF{093907da-19e3-4a15-aa56-62f77cd92f66}
3、ezmd5
查看源码可知这题就是进行一个图片的md5值的比较,并且要求是两个图片不一样但是md5的值要一样
于是上网寻找,还真在csdn的一个博客里面找到了两个图
https://blog.csdn.net/rclijia/article/details/114400242
把原文地址的两个图片上传上去就可以得到flag
XYCTF{1b3eb8cc-336a-45b9-a376-e98c9cfb9adc}
Reverse
1、聪明的信使
拖进die一看是32位的程序,于是用ida打开
按F5看源码
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
发现一个很像flag{}的东西
oujp{H0d_TwXf_Lahyc0_14_e3ah_Rvy0ac@wc!}"
查看encrypt函数的源码
1 | int __cdecl encrypt(char *a1, int a2) |
跑一个gpt,告诉我如下:
1 | 这段代码是一个简单的加密函数,接受一个字符串和一个整数作为参数。它通过将字符串中的每个字母按照指定的偏移量进行加密。 |
发现这就是一个简单的凯撒密码
那么这个函数的逻辑就不言而喻了,所以encrypt函数的逻辑就是输入一个字符串和一个偏移量,然后进行凯撒密码移位处理
从源码得知移位量是9,并且后续是和 oujp{H0d_TwXf_Lahyc0_14_e3ah_Rvy0ac@wc!}"
比较要相等,所以可以把这个字符串逆向移位,得到flag
flag{Y0u_KnOw_Crypt0_14_v3ry_Imp0rt@nt!}
2、喵喵喵的flag碎了一地
拖进die一看发现是64位程序,用ida64打开
F5看源码得到提示
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
第一个hint要我们看strings,那就看,shift+F12得到
flag{My_fl@g_h4s_
第二个hint让我们看fuctions,那就看
得到
br0ken_4parT_
给了提示
1 | int br0ken_4parT_() |
提示要让我们找引用了这个函数的函数,那就找
按x得到
于是跳转到fuction718,得到最后一部分flag
Bu7_Y0u_c@n_f1x_1t!}
所以完整的flag为
flag{My_fl@g_h4s_br0ken_4parT_Bu7_Y0u_c@n_f1x_1t!}
赛后复盘
1 | https://blog.csdn.net/qq_42557115/article/details/138267583 |