西电CTF平台——MoeCTF 2023 WriteUP
古典密码ezrot
rot类解码,一个一个解码,最终rot47解码得到flag。
vigenere
既然提示了是维吉尼亚密码,需要知道个key。维吉尼亚的特点跟异或一样,假设AB=C,那么AC=B,B^C=A,根据这个原理,直到答案肯定是moectf开头的,所以先拿moectf作为key,拿到真正的key为goodjo。
文档还给出了flag的md5,计算一下,发现不对。
结合key中goodjo不像一个完整的英文单词,猜测应该是goodjob,解密成功。
不是“皇帝的新密码”
跟上一题一模一样
可可的新围墙
通过"新围墙"可以很容易地想到栅栏解密。但是这题是个w型栅栏,编写脚本解密。
def dec(encrypted, num): matrix = [( * len(encrypted)) for i in range(num)] cur = 0 for i in range(num):# 按行来填 # 生成每行空格个数的取值序列 if i == 0:# 第1行和最后一行,只需要一个取值就好了 pair = [(num - (i + 1)) * 2 - 1] elif i == num - 1: pair = else: pair = [(num - (i + 1)) * 2 - 1, i * 2 - 1] # 按规则填入 pair_i = 0 j = i while True: if cur < len(encrypted): matrix = encrypted cur += 1 j += pair + 1# 这里要加1,直接加间隔是不够的 pair_i += 1 if j >= len(encrypted): break # 临时输出 # for i in range(num): # for j in range(len(encrypted)): # print (matrix, ' ') # print() # 获取i的取值序列 i_s = [] for a in range(num): i_s.append(a) for a in range(num - 2, 0, -1): i_s.append(a) i_s_len = len(i_s) # 按规则取出 decrypted = '' for j in range(len(encrypted)): decrypted += matrix] return decryptedciphertext = 'mt3_hsTal3yGnM_p3jocfFn3cp3_hFs3c_3TrB__i3_uBro_lcsOp}e{ciri_hT_avn3Fa_j'for i in range(2, len(ciphertext)): plaintext = dec(ciphertext, i) if "moectf" in plaintext: print(plaintext) # moectf{F3nc3_ciph3r_shiFTs_3ach_l3TT3r_By_a_Giv3n_nuMB3r_oF_plac3s_Ojpj}猫言喵语
文件内容如下。
喵喵? 喵喵喵喵喵喵喵喵喵喵喵喵 喵喵喵 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵喵喵喵? 喵喵喵喵喵? 喵喵喵喵喵?喵喵? 喵喵喵喵喵? 喵喵喵喵喵喵 喵喵喵喵喵喵 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵喵喵喵?喵喵喵 喵喵喵喵喵? 喵喵? 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵喵喵喵喵喵喵喵 喵喵喵喵喵喵喵喵? 喵喵? 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵喵喵喵喵喵喵喵 喵喵喵 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵喵喵喵?喵喵喵 喵喵喵喵喵? 喵喵喵喵喵?喵喵喵喵喵喵 喵喵喵喵喵?喵喵喵喵喵喵 喵喵喵 喵喵?喵喵喵喵喵喵 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵?喵喵喵 喵喵?喵喵?喵喵? 喵喵喵喵喵喵喵喵? 喵喵?喵喵?喵喵喵喵喵喵 喵喵喵喵喵喵 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵?喵喵喵喵喵喵喵喵喵 喵喵?喵喵喵喵喵?喵喵? 喵喵喵喵喵喵喵喵?喵喵?喵喵喵喵喵? 喵喵喵喵喵?喵喵喵 喵喵?喵喵喵喵喵喵喵喵?根据文件提示"Morse code",是摩斯密码。众所周知。摩斯密码只有两种符号,所以得把文件内容根据特征划分成两块。内容中的空格相当于分隔符,根据观察,可以看出"喵喵?"是一组,"喵喵喵"是一组,根据这个规律进行转换,得到如下内容。
./----/-/--..-./.-./-./-../-./--/--/--..-./.-.-/-././--..-./.---/--././--..-./.---/-/--..-./.-.-/-./-.--/-.--/-/.--/--..-./..-/.../--./..--/--/--..-./.---/.-../--..-./-.-/.--.解码发现有问题,将"-"和"."交换一下解码成功。
套上moectf{},提交即可。
皇帝的新密码
通过"皇帝"两个字再结合我们所知道的古典密码,只有凯撒密码了,当偏移量为7时获得flag。
安全杂项
base乐队
附件内容如下。
HFUEULC5HEZG42DGHFGDWSCTHRCUIUSVHFGDWS2EGZMCCRDKG5XG2LDEHFUTYYZGHJSUMKKDGVZDELBRHBIW4UCQGZLGOP2SHEYV44ZOHEZFYXCZHEYUIV2VGEXVK4KRHBWFWY2OHVMWSYCKG5XFCZTBHEZC6I2WHJST2ZK4HEXTSMDSHA3CKZRZGRNHI4LL
根据题目意思,应该是base家族的一些加解密,经过尝试,经过一次base32、一次base85、一次base32可以解出如下内容。
看起来也像是base编码,但是为什么中间会有一个等号?这里卡了好久,经过尝试,需要先进行一次栅栏解密,在进行base64解码即可还原。
building near lake
这题跟信息泄露有关,附件是个图片,先通过百度搜图看看是哪里。
根据原图中的umx和搜索结果可以定位到厦门大学,搜索厦门大学的经纬度。
题目中说使用的是BD09坐标系,所以就要将GPS坐标转为BD09坐标。
function wgs84ToBd09(lng, lat) {var pi = Math.PI * 3000.0 / 180.0;var x = lng, y = lat;var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);var bdLng = z * Math.cos(theta) + 0.0065, bdLat = z * Math.sin(theta) + 0.006;return {"bdLng": bdLng, "bdLat": bdLat};}
还差一个拍摄设备的发布会时间,查看图片的详细信息,发现是小米的设备,照相机型号为22122RK93C。
网上搜索,可以发现改照相机型号用于Redmi k60手机上,搜索Redmi k60手机的发布会时间得到2022年12月27日。
填上相关信息,提交获得flag。moectf{P0sT_Y0uR_Ph0T0_wiTh_0Riginal_File_is_n0T_a_g00d_idea_YlJf!M3rux}
打不开的图片1
下载得到一个破损的文件,用16进制编辑器打开,看到文件头和文件尾就可以想到是个jpg格式的文件。
但是文件头有点不对,将第二个字节改成D8,保存为jpg格式。
打开图片,啥也没有,右击属性,在详细信息中看到一串16进制编码,解码得到flag。
打不开的图片2
这次显示文件是个jpg格式的图片,但是打不开,16进制编辑器打开,看到文件头出现了IHDR头,就可以想到其实是个png格式的图片,再看到文件尾,更加证实了是个png文件。
修改文件头前4个字节为89504e47,保存。
打开图片,即可看到flag。
杂项
Misc 入门指北
文档最后有个base64编码的字符串,直接解码即可获得flag。
weird_package
打开是个损坏的压缩包,不过我们有个强大的工具winrar,它有修复压缩包的功能,让其修复,解压得到9个文件。
16进制打开所有的文件,都是些base64编码字符串,尝试去解码,但都是乱码。
FcbNCoJAEADgV1L3NAcvpbP2N4HarDtHcWuTWRCCiJ5+6/DBNztQb/oUzPJeSigGq9+p+sO7JDwLQxotdlMR42Dx4BlGWmWb2554pdZXKvLE163Zbc59Tr/TxRzL0Gh3ZYH9o64zDcPBDoIwDADQX2KdJvbABVmniS6x0IHHoaiJnXqb8evx8KYB9Ww5z/ZSrgar5LUf4a+iGz/pwBH95Og1wqNJjt6niKvjL3ySuNJlNdI2bt5FI77A0FEf82a9FxMEvoFBcXuv6wU=FcqxDsIgEADQX6Iw3dAF4x0x0kRSr7Rb8VQGLjoZ9eurw9temaDNLunVyUs6MCu1b7Z/eEuKx4WBCmHIttaV8DEzDBd9LylwJ2PzxZzsmA8+7uUZDQ6s4Kczfn4nRMewu/f9Bg==FcPBDoIwDADQX3Ls1CuRYmLGAUZHe0PFLGbVxB5Uvn7x8C4JCvtRN3/93BzMa1/i0vzhXRTfQqAh4XNpcl57fDFBG3bpNmwtpq+b98EmlRMf8Dd6OtNjsHCUjl2xOCFUFcOxCsIwEADQXzIpHW4VvIhCxPZsmttOG4kkZ8DBoV9fOrxngBq7QVO3/BcDB3F1ne0O36z44wlUAn5nm7M4bHECGj+nTMT+pWxuoWpypZcRr4MFpUdbfbn30Rx9Ol9gAw==FcNRC4JADADgv6QnQXvwKdw0mNAd3uneOqwkNpACkX699PDlBDpV3h7VvM0lDIH0N7o/fIrhRyJYJmzHYlkCYTfF84nbqwxOt2D9KsquN/36pkxc+Pc9qnVpvzGp5GaFy6uuDw==FcOxDoIwEADQX/LOxRtYMBwu19iCLbBRqzbaU6KL8euJw4uByrh1eoF09ECbuS39gH98nZTfAqQS+DlgznPLr9HvMIIxKXyXE9d32wu6Q7axgU/y8ovNog5NfX4k6MpE+1tVrQ==FcPNEoIgEADgVwI57cFTuUx/NK7pIkekYobWI00+vdPhiwyf2ZA8TapJgxps0b75w1cQvIYJJFpcvcp5sHiaJ6h0DG4p3ZeasvWj5qgw9P78i92yJXb1MZLcTL7c2cHh3bY7FcPBCsIwDADQXzJuHnL0UEIFGbZLtuxmN4tIIoIgY18/PLwyoGmT/AFLVEk1kYUR7LcIhgLIf5mk6nh5ZbLj1GONw3q7kk0lfDzyYZvf0nY8n8T1mR3bO8O3689boRV3
多串字符串,想法是base64隐写,尝试了一下,没有内容。
其实cyberchef里有个强大的算法magic,用完之后知道还需要进行Raw_Inflate解码才能得到正确的明文。
不过这九个里面只有最后一个解出来的才是最终flag。
你想要flag吗
拿到一个wav文件,直接先用audacity打开,查看频谱图,看到key和pwd。
wav中应该是隐藏了一个什么加密的文件需要用pwd去解压,利用steghide去分析一下。
解压得到兔兔.txt,打开,一眼看过去像是base64加密,解压看到有salted字样,想到了AES加密和Trible DES加密,尝试用key去解密。发现都解密不出来,最后尝试了一下rabbit加密,成功解密。
https://img2024.cnblogs.com/blog/3369335/202506/3369335-20250627185253535-365769518.png
套上moectf{}即可。
奇怪的压缩包
附件是一个zip文件,打开看到如下内容。
有经验的可以很容易看出其实是个ppt文件,不知道也可以利用kali里面的file命令来识别,修改后缀为ppt打开。
这种题就是ppt隐写了。第一张图片没有什么内容,第二张图片的文字颜色跟背景颜色一样了,需要修改颜色才能看到。
原始的:
修改颜色后:
第三张图片原始图如下:
将妙蛙种子移开就可以看到内容。
第四张图片原始图如下:
也是将妙蛙种子移开看到内容。
第五张图片原始图如下:
但是找了半天也没找着,原来藏在了大纲中。
将4部分拼接起来得到moectf{2ip123456n0_i4_pp4x!}提交,发现不对。还是第三张图片有问题,因为旁边有个注解,会不会要表达的不是123456,而是_?_呢(这个我真的是看完所有ppt的xml文件,发现已经找不到任何东西了,灵机一动换的,足足耗了我2个小时,我晕),修改完之后,最终答案为"moectf{2ip_?_n0_i4_pp4x!}",提交成功。
尊嘟假嘟?
附件内容如下。
Ö_o owO 0v0 Owo o.O O.O Ö.0 OwO ÖwO 0wO Ov0 OwO Ö.O ÖvÖ Ö.0 Ov0 o.O OvÖ 0w0 OvO o_0 O.Ö Öw0 Ö_0 Ö.O Ö.O O.0 owo ÖvÖ O.o Ö.0 Övo o_0 ÖvÖ 0w0 Ö_0 Övo ow0 Ov0 Ö.0 Öwo 0wÖ O_0 O.Ö o_o 0wÖ Ö.0 Övo Ö.o Ö.Ö Övo ovo Ö.O Ö.o o_0 O.o ÖvO owO 0_0 owO Ö_o 0wÖ Öv0 0wO o.O OwÖ Öw0 O.o Öw0 O.o 0.0 O_O Ö_0 Ö.o Ö.0 0v0 Öw0 Ö.O 0_0 0vÖ Övo owÖ Ov0 0_Ö Öv0 Ö.Ö O.0 0vÖ Ö.o 0vÖ 0.0 OwÖ ÖvÖ ÖvÖ o_0 0_0 ÖwO Ö.O Övo ovo o.O 0vo Ö.0 owo Öv0 ÖvÖ Öw0 Öwo Ö.0 Ö.O o.0 O_Ö o_o O.0 Ö.0 Öwo Ö.o Ö.O ov0 Öw0 Ö_o owÖ Ö.0 Ov0 o_0 Ö.O ov0 Ö.0 Öwo Ö.O o_0 owo o_o O.Ö 0.0 OvÖ Öw0 Ö.O 0_0 ÖvÖ Ö.0 Ö.Ö 0w0 O.O Ö_o owÖ Öv0 O.O Ö.0 O.o ov0 OvÖ ÖvÖ Ö.0 0.0 Ö.O ÖvO O.o Ow0 O_o Ö.O 0vo ov0 OvÖ o.Ö OwÖ Ö.0 0w0 o.O owÖ 0.0 O_Ö ÖvÖ Ö.0 O_0 Ö_0 Öw0 Ö.O O_0 0wO o_O Ö.o O_0 Övo Öw0 ow0 O_0 ÖwO Ö.0 Ö.O Ö.0 O.Ö Öv0 O.o Ö.0 Ö_0 o.Ö ow0 Ö.0 0wÖ OvO 0vO 0_0 0v0 o_O ÖvÖ 0.o 0wo o_0 O.O 0w0 0v0 O_o O.Ö Öv0 0w0 o.O Ö.O Ow0 0.0 o.Ö 0vO o_o 0wo ÖwO OvO Ov0 0wO o_O Ö.Ö Öv0 0v0 o_o OwO Ov0 0_Ö Ö_0 0wO Ov0 0.o Ö_o Ö.Ö Öw0 0.o O_o O.O o.0 0vO O_o OvO O_0 ovO o_0 Ö.O ov0 0vo o_0 Ö.O 0.0 0.0 Ö_o Ö.O Öv0 ow0 ÖwÖ OwO O_o 0wo o_0 owO 0w0 0.0 Ö_o owO 0wo 0wo Ö_o 0vO Ö.0 0vÖ o.O Ö.O ovo 0wo o_0 owO 0v0 owo o.O OvO Ov0 0wO Öw0 0wÖ Ovo ov0 Öwo ÖvÖ 0vo Owo Öw0 O.O Öw0 0vo Ö_0 0vO O_o O_O o.O Ö.Ö Ö_o ovO O_o O.Ö Öv0 0.o Ö_0 ÖvO Ov0 0v0 o.Ö 0vO Övo 0wo ÖwO OvO Ov0 0wO o_O Ö.Ö Öv0 0v0 o_o OwO Ov0 0_Ö Ö_0 0wO Ov0 0.o Ö_o Ö.Ö Öw0 0.o O_o O.O o.0 0vO O_o OvO O_0 0vo o_0 Ö.O Öv0 ow0 Ö_0 O.Ö Ö.o Ö_Ö O_o 0wO Ov0 owÖ o.O O.O 0v0 0wÖ o.O OvO Ov0 0wO Ö_0 Ö.O o_0 0.0 o.Ö 0wO Ov0 owÖ o.O Ö.Ö Öv0 0.o O_o OvÖ O_o owÖ Öwo 0vO O_0 0vO Öwo Ö.O Öv0 0w0 Öwo 0wÖ O_o Owo Öw0 Owo 0.o O_O o.O O.O 0v0 0_O o_0 OvÖ O.o ovO O_o O.O 0w0 0_Ö o_0 OwO Ov0 0vo o.Ö OwO Ov0 OvO o.O Ö.Ö Öv0 0wÖ o.Ö owO 0v0 0_O O_o O.O O.0 0vo Ö_0 O.Ö O_0 0v0 o_o owÖ Öw0 0v0 o_o OwO Ov0 0v0 o.Ö 0vO Öw0 0_Ö Ö_0 O.O Ö.o Ö_Ö OvO 0vO 0w0 0.0 o.Ö 0vÖ Övo OwO ÖwO 0wO Ov0 owo o.O O.O Ö.o 0wo o.Ö 0vO O.0 0_0 Ö_0 ÖvO Ov0 0_Ö Ö_0 0wO Ov0 0wÖ o_o 0vÖ 0v0 Owo o_0 O.O o.0 OwÖ o_O Ö.Ö Öw0 owo Ö_0 Ö.O owo 0wo o.O Ö.Ö Öwo 0wo O_o 0vO O_0 0_o O_O 0wO 0.o 0.O O_O 0vÖ Öw0 0.o O_o 0wo上网搜索了一下"尊嘟假嘟?",发现是个网络流行用语。
一开始以为是要将附件中的内容根据尊嘟假嘟翻译成上图中框起来的的符号,但是附件中的内容不止三种,此法不通。
上谷歌翻阅了大量资料,终于找到了一个尊嘟假嘟转换器(https://zdjd.vercel.app/),转换一下。
翻译得到的内容如下。
cipher: rY5Ah8BtsYYatLEPu8YCPU22Gr5PQt8YGDKkvb4bk3D4JJeEe5kgCpoEqgRzsM7m9d8jEtE3LUoKpULQnMcuAunU1gtpzC5kSUxFctFTNCMZVHLHZNCo5akzKMRY5bbyBP7RNUeGDEYoUckey: the tailing 8 bytes of hash of "zundujiadu?" which begin with b6091904cdfbiv: the end 8 bytes of hash of "dududu?" which begin with 272bf1da2207hint1: how do Bitcoin addresses encode?hint2: the name of cryptosystem is "bl****sh"根据提示对zundujiadu?和dududu?进行sha256加密
根据第一个提示对比特币地址如何编码进行搜索
有base58编码,再根据第二个提示看哪个加密方式是bl开头,sh结尾的,找到blowfish算法。
对密文按照base58、blowfish、base64的顺序解码得到flag。
机位查询
附件给了我们三张图片,叫我们找到这三张照片分别是在哪栋楼拍的。
第一张照片可以看到南宁站和中铁快运营业部,放大还可以看到猪霸王煮粉,直接百度地图上搜,就可以定位到大概的位置了。
候选地点是嘉士摩根国际。
第二张照片是最简单的,直接百度识图,可以看到有个人在小红书上刚好发布过这张图片,直接拿到了拍摄地点。
https://www.xiaohongshu.com/explore/5f223da3000000000101f3f2
第三张照片是最头疼的,全都是高楼,能够看到的只有广西农信,时代丽都,搜索相关位置,找到了大概区域。
但是能够拍到这张图片的位置可不少。试了好久也没试对。最终在图片的属性信息中看到了有经纬度。接下来就可以定位了。手机上下载"经纬度定位"app,输入经纬度就得到了地址。(一开始用谷歌定位一直定位不出来,真的是日了)
经度:108; 21; 33.0084219999844919纬度:22; 48; 48.3576960000066
最终将三个地点的前两个字的拼音进行拼接即可,即jiashi_baisheng_huijin。
这题做了2个多小时,人都麻了。
烫烫烫
根据锟斤拷锟斤拷锟斤拷去搜索相关知识。
https://zhuanlan.zhihu.com/p/583712101
说明在编码方面出现了问题,尝试用utf-8解码,没有效果,换了几个编码方式,才知道是utf-7。
得到如下内容。
这是你的flag:a9736d8ad21107398b73324694cbcd11f66e3befe67016def21dcaa9ab143bc4405be596245361f98db6a0047b4be78ede40864eb988d8a4999cdcb31592fd42c7b73df3b492403c9a379a9ff5e81262但是flag用AES加密了,key是下面这行字的sha256(hash值的开头是b34edc782d68fda34dc23329)所以说,codepage真的很重要啊(对所以说,codepage真的很重要啊(进行sha256加密得到key为b34edc782d68fda34dc2332967273b0f0900a0ebd0dcec48467851bc6117bad1,然后进行aes解密拿到flag。
照片冲洗
附件是一张图片,提示说不小心把两张照片粘在一起了,说明附件的图片是由两张图片拼在一起的,需要将其分离。
先利用binwalk去分析,发现没有。
再用zsteg命令,发现有隐藏信息,明显是png文件的头。
用16进制编辑器打开图片,搜索"49484452",可以发现有两个。
只不过后面这张图片的文件头都为0,将后面这部分的16进制剪切出来,将文件头改成89504e470d0a1a0a即可。
打开俩张图,发现图都是一样的,第一反应就是盲水印,利用github上的脚本(https://github.com/chishaxie/BlindWaterMark) 解密。
打开解密的图片,发现啥都没有。是不是思路错了呢?再试一下将两张图片进行重叠,这里需要利用stegsolve.jar工具,尝试了add、xor、sub等结合方式都没发现。最后发现盲水印还有一种频域提取方式,这里利用github上的工具(https://github.com/Byxs20/PuzzleSolver)。
设置好后,点击开始执行,得到的图片如下。
发现是有信息,但是很模糊,这里还是利用stegsolve.jar工具,在Color Inversion通道中看得稍微清楚点。
套上moectf后得到:moectf{W0w_you_6@v3_1earn3d_blind_w@t3rma2k}
狗子(1) 普通的猫
下载得到一个音频,用audacity打开没有什么发现。最后用16进制编辑器打开,flag就藏在文件尾。
狗子(2) 照片
图像隐写题,直接利用kali系统中的几个常用的分析图片的命令就可以了。
先利用strings命令看图片的二进制代码中是否包含flag。
没有再看图片中是否含有其他文件,利用binwalk命令。
也没有,接下来就是利用zsteg命令看图片是否存在隐写。
找到了,手工完事。
狗子(3) 寝室
这题是个压缩包的循环嵌套,包含tar.gz,tar,zip,7z四种类型的压缩包格式,直接编写脚本解压。
import tarfileimport zipfileimport py7zrimport osname = 'ziploop.tar'while True: print(name) index = name.find('.') suffix = name if suffix == '.tar' or suffix == '.tar.gz': tar = tarfile.open(name) tar.extractall(path=os.path.split(name)) name = tar.getnames() elif suffix == '.zip': with zipfile.ZipFile(name, 'r') as zip_ref: zip_ref.extractall(path=os.path.split(name)) name = zip_ref.filelist.filename elif suffix == '.7z': file = py7zr.SevenZipFile(name, mode='r') file.extractall(path=os.path.split(name)) name = file.getnames() print(name)最后解压出一个flag.txt文件,里面就是flag。
狗子(4) 故乡话
得到内容如下,只有true和false,第一反应就是需要将其转换成01字符串。
看样式转字符根本不可能,去掉1,看这些0组成的图案,有点感觉像矩阵图。
结合提示“狗子所用的语言,似乎在地球上某款知名沙盒游戏也出现过”,说的应该是“我的世界”中的银河字母。
看0中间包围的图案对照银河字母,得到flag。moectf{dontanswer}
计算机基础
CCCCC
代码如下。
#include#includeint main(){//unsigned char flag[]="moectf{HAHA_C_1s_easy!}";unsigned char enc_data[]="mng`pc}OIAKTOR?|Ots`m4k",flag;int i;for( i=0;i 0: pic.putpixel(,(255, 255, 255)) else: pic.putpixel(,(0,0,0))pic.save("flag.png")得到一张二维码。
在线扫描得到flag。
A very happy MLP
需要理解torch.nn.Linear函数的运算方式,然后只需要写出sigmoid()以及fc()的反函数即可直接求得flag,梯度下降反而不能得到正确的flag,
import torchimport numpy as npfrom model import Netdef inv_fc(y, weight, bias): return torch.matmul(y - bias, torch.pinverse(weight).T)def inv_sigmoid(y): return torch.log(y / (1 - y))def float2chr(f): return chr(int(np.round((f + 1) / 2. * 255.)))def verify(flag_path): def verify_flag(flag_tensor): checkpoint = torch.load('_Checkpoint.pth') net = Net() net.load_state_dict(checkpoint['model']) base_input = checkpoint['input'] output = net(base_input + flag_tensor) return torch.equal(torch.round(output.detach(), decimals=5), torch.tensor()) def show_flag(flag_tensor): flag = '' for f in np.array(flag_tensor).ravel(): flag += float2chr(f) print('moectf{' + flag + '}') try: flag_tensor = torch.load(flag_path).detach() except: print('Invalid flag path.') return if verify_flag(flag_tensor): print('You made this little MLP happy, here\'s his reward:') show_flag(flag_tensor) else: print('Sad :(')net = Net()# Load model and base_inputcheckpoint = torch.load('_Checkpoint.pth')net.load_state_dict(checkpoint['model'])base_input = checkpoint['input']intended_out = torch.tensor()intended_fc3_inp = inv_fc(intended_out, net.fc3.weight, net.fc3.bias)intended_fc2_out = inv_sigmoid((intended_fc3_inp + net.scale / 2) / net.scale)intended_fc2_inp = inv_fc(intended_fc2_out, net.fc2.weight, net.fc2.bias)intended_fc1_out = inv_sigmoid((intended_fc2_inp + net.scale / 2) / net.scale)intended_fc1_inp = inv_fc(intended_fc1_out, net.fc1.weight, net.fc1.bias)out = net(intended_fc1_inp)assert torch.equal(torch.round(out.detach(), decimals=6), intended_out)flag_tensor = intended_fc1_inp - base_inputtorch.save(flag_tensor, '_ExpFlag.pth')verify('_ExpFlag.pth')现代密码学
ABC
题目给出了3个npy文件,直接利用numpy库读取,判断每个数组的大小,并将三个矩阵相乘。
import numpy as npa = np.load("a.npy")b = np.load("b.npy")c = np.load("c.npy")abcm = np.matmul(np.matmul(a, b), c)查看乘完之后的结果,发现不是-1就是1,原本想按照颜色进行区分显示出来,但是看了半天也没看出什么东西。卡了很久之后,才想到将-1对应的点变成黑色像素点输出,将1对应的点变成白色像素点输出,果真得到了一个二维码。
import numpy as npfrom PIL import Imageimport matplotlib.pyplot as plta = np.load("a.npy")b = np.load("b.npy")c = np.load("c.npy")abcm = np.matmul(np.matmul(a, b), c)abcm = np.int8(abcm > 0)# print(abcm)aa = np.asarray(abcm)g = Image.new('RGB', (29, 29), color='white')for i in range(len(aa)): for j in range(len(aa)): if aa == 0: g.putpixel((i, j), 0)g.show()g.save('./1.png')
扫码得到flag。
Crypto 入门指北
把代码运行一下就能拿到flag。
from Crypto.Util.number import * # 一个非常好用的crypto库p = 0xe82a76eeb5ac63e054128e040171630b993feb33e0d3d38fbb7c0b54df3a2fb9b5589d1205e0e4240b8fcb4363acaa4c3c44dd6e186225ebf3ce881c7070afa7q = 0xae5c2e450dbce36c8d6d1a5c989598fc01438f009f9b4c29352d43fd998d10984d402637d7657d772fb9f5e4f4feee63b267b401b67704979d519ad7f0a044ebc = 0x4016bf1fe655c863dd6c08cbe70e3bb4e6d4feefacaaebf1cfa2a8d94051d21e51919ea754c1aa7bd1674c5330020a99e2401cb1f232331a2da61cb4329446a17e3b9d6b59e831211b231454e81cc8352986e05d44ae9fcd30d68d0ce288c65e0d22ce0e6e83122621d2b96543cec4828f590af9486aa57727c5fcd8e74bd296e = 65537n = p*qphi = (p-1) * (q-1) # 你知道什么是 欧拉函数吗 d = pow(e, -1, phi) # 什么是乘法逆元? m = pow(c,d,n)print(long_to_bytes(m)) # b'moectf{weLCome_To_moeCTf_CRypTo_And_enjoy_THis_gAme!_THis_is_yoUR_fLAg!}'baby_e
代码如下。
from Crypto.Util.number import getPrime,bytes_to_longp,q = getPrime(2048),getPrime(2048)e = 7n = p*qm = bytes_to_long(open('flag.txt','rb').read().strip())c = pow(m,e,n)print("c = ",c)print("n = ",n)# c =147693154873835354725007152781732424355869776162377337823960431913672366269917723916891506269449726723757821517328874729037838600793748824028829185409932536014732765063216715033843955453706710187792772702199448156372644163429786386035008302836467605094954587157232829525150652611067567669525072625329634860065850520051628272535479197120008981979404760445193750864902244921407742155742716289495581989134730376783828846663464819337418977287363028738701414486788851136608957124505485242331701209645216580641917007780811842757125048746184068597664780265422321550909392419865169775282217442331295071069272774722564587602419768461231775480847018941840911357926330143045826277813722919121117172763493242590521245640828462665947672485094793188432098216701511715232654611338293295459889814699850788048985878279440740712956248569068077253790198036918598519191892836075254345518967666166925163908185663991353344555402397055977817370082929420443034626201745027965444069777059760865359310439815816749939498993014457995041394803598825093836045546578310632172636478575946653375857640993393714607308326474003446154152048840071034349831168612740218034679021240949747357214453636633636662650940968576792518622437627529244515229173# n =553409369582823237678532685244026647155180191225879439432235077135813123637186465008813830373646133388592395760175777499266561095087891764348044063111935877931069321764391883899483374576303169645488542398590564148654412004383012178107972880058460460806768779452529433458826925606225797078653905380530651390617109384086518728626571028089036812787671647095695947167204428442727185744172445701874820612799168887428075695751162763647868386879374037826876671079326544820609721731078985096813307183878793033824330869698508952853770794414757655681370862323768018291030331209143189638496644361618184164228294031490537429556439588954274708598530042700988138862000054458742762198052079867259365645914383561162796796952346445529346145323567650621600171442575319262718389389870407629339714751583360252884338116164466349449862781112019462555743429653595045695696967783338371470032332852204294900011651434678829104876529439166176589508898757122660322523937330848536715937381297551894198974459004139082562228022412335520195652419375915216074658463954339332593244483927157329404652516225481116614815221154229491846087288087715884363786672244655901308480290011237244562251084095684531716327141154558809471185132979704992609461470501119328696999713829题目中给出了e,c,n。我们都知道rsa算法最重要的是需要知道p,q,e,其他的变量都可以根据这三个变量得到。
n=pq
dp=(p-1)(q-1)
c=pow(m,e,n)
m=pow(c,d,n)
题目中的p和q是随机生成的,长度都为2048,但是有n,所以第一想法是去暴力分解n。这里介绍两个常用的分解大素数n的工具。一个是在线网站,一个是yahu。我尝试了这两个工具,但是因为n实在太大,无法分解。
既然分解不出来p和q,就换一种思路。我们可以观察到e很小,但是n很大,加密的c=(m^e)mod n,当men时,则有me=k*n+c,对k进行爆破。编写脚本:
import gmpy2e = 7c = 147693154873835354725007152781732424355869776162377337823960431913672366269917723916891506269449726723757821517328874729037838600793748824028829185409932536014732765063216715033843955453706710187792772702199448156372644163429786386035008302836467605094954587157232829525150652611067567669525072625329634860065850520051628272535479197120008981979404760445193750864902244921407742155742716289495581989134730376783828846663464819337418977287363028738701414486788851136608957124505485242331701209645216580641917007780811842757125048746184068597664780265422321550909392419865169775282217442331295071069272774722564587602419768461231775480847018941840911357926330143045826277813722919121117172763493242590521245640828462665947672485094793188432098216701511715232654611338293295459889814699850788048985878279440740712956248569068077253790198036918598519191892836075254345518967666166925163908185663991353344555402397055977817370082929420443034626201745027965444069777059760865359310439815816749939498993014457995041394803598825093836045546578310632172636478575946653375857640993393714607308326474003446154152048840071034349831168612740218034679021240949747357214453636633636662650940968576792518622437627529244515229173n = 553409369582823237678532685244026647155180191225879439432235077135813123637186465008813830373646133388592395760175777499266561095087891764348044063111935877931069321764391883899483374576303169645488542398590564148654412004383012178107972880058460460806768779452529433458826925606225797078653905380530651390617109384086518728626571028089036812787671647095695947167204428442727185744172445701874820612799168887428075695751162763647868386879374037826876671079326544820609721731078985096813307183878793033824330869698508952853770794414757655681370862323768018291030331209143189638496644361618184164228294031490537429556439588954274708598530042700988138862000054458742762198052079867259365645914383561162796796952346445529346145323567650621600171442575319262718389389870407629339714751583360252884338116164466349449862781112019462555743429653595045695696967783338371470032332852204294900011651434678829104876529439166176589508898757122660322523937330848536715937381297551894198974459004139082562228022412335520195652419375915216074658463954339332593244483927157329404652516225481116614815221154229491846087288087715884363786672244655901308480290011237244562251084095684531716327141154558809471185132979704992609461470501119328696999713829k = 0while 1: res = gmpy2.iroot(k * n + c, e) if res: print(bytes.fromhex(hex(res))) # b'moectf{SMaLL_3xPon3nt_Mak3_rSa_w3ak!_!lP0iYlJf!M3rux9G9Vf!JoxiMl903lllA}' break k += 1bad_E
源代码如下。
from Crypto.Util.number import *p = getPrime(512)q = getPrime(512)e = 65537print(p) # 6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571print(q) # 11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819with open("flag.txt","r") as fs: flag = fs.read().strip()m = bytes_to_long(flag.encode())c = pow(m,e,p*q)print(c) # 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805因为我们知道了p和q,第一反应就是求出d,那这题不就解决了吗。可问题就出现在求d上了。我们都知道d是当e和(p-1)*(q-1)互素的情况下求出来的逆元,可是这题e和(p-1)*(q-1)不互素,所以用常规的方法就不行了。求gcd(e,(p-1))和gcd(e,(q-1)),发现e与q-1互素,而我们都知道有以下公式:
m = c^d mod n==>m=c^d mod pm=c^d mod q(注:此推论满足的前提是------在c不是p或q的倍数,以及d是正整数的情况下,m = c ^ d modp 和m = c ^ d modq 总是成立的,有兴趣的同志们可以自行查找推导过程,这里就不过多说了)故这题可以使用以下代码求解:
d = invert(e,q-1)m = pow(c,d,q)完整代码如下:
from Crypto.Util.number import *import gmpy2p = 6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571q = 11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819c = 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805e = 65537n = p * q# a = gmpy2.gcd(e, p - 1)# b = gmpy2.gcd(e, q - 1)# print(a, b)phi = (q - 1)d = gmpy2.invert(e, phi)m = pow(c, d, q)print(long_to_bytes(m)) # b'moectf{N0w_Y0U_hAve_kN0w_h0w_rsA_w0rks!_f!lP0iYlJf!M3ru}'factor_signin
源代码如下
from Crypto.Util.number import getPrimefrom math import prodwith open("flag.txt","rb") as f: flag = f.read().strip()assert len(flag) == 72m1 = int.from_bytes(flag[:36],"big")m2 = int.from_bytes(flag,"big")e = 65537p,q = getPrime(2048),getPrime(2048)n1 = p*qc1 = pow(m1,e,n1)print("c1 = ",c1)print("n1 = ",n1)primes = # 随机生成32个素数n2 = prod(primes) #对primes列表中的数字计算乘积c2 = pow(m2,e,n2)print("c2 = ",c2)print("n2 = ",n2)# c1 =10004937130983861141937782436252502991050957330184611684406783226971057978666503675149401388381995491152372622456604317681236160071166819028679754762162125904637599991943368450200313304999566592294442696755822585022667008378021280392976010576970877334159755332946926433635584313137140987588847077645814987268595739733550220882135750267567373532603503399428451548677091911410732474324157868011686641243202218731844256789044721309478991918322850448456919991540932206923861653518190974620161055008847475600980152660468279765607319838003177639654115075183493029803981527882155542925959658123816315099271123470754815045214896642428657264709805029840253303446203030294879166242867850331945166255924821406218090304893024711068773287842075208409312312188560675094244318565148284432361706108491327014254387317744284876018328591380705408407853404828189643214087638328376675071962141118973835178054884474523241911240926274907256651801384433652425740230755811160476356172444327762497910600719286629420662696949923799255603628210458906831175806791599965316549386396788014703044837917283461862338269599464440202019922379625071512100821922879623930069349084917919100015782270736808388388006084027673781004085620817521378823838335749279055639005125# n1 =343504538870081878757729748260620800783581983635281373321527119223374418103340873199654926888439040391545101913132680017655039577253974802351999985470115474655124168592386965001556620077117966153475518658881140827499124290142523464795351995478153288872749817655925271395693435582010998996210909883510311066017237567799370371513462802547313382594409676803895262837061350017911885033133654781876923251129406855067993830824618637981136966134029212516871210627954762147349788788999116702635535406398258621926040887099782494271000823401788337120154104692934583729065189687995570122890809807661370008740283447636580308161498808092269041815719148127168137018600113465985504975054319601741498799761500526467431533990903047624407330243357514588557352746347337683868781554819821575385685459666842162355673947984514687068626166144076257334426612302554448774082488600083569900006274897032242821388126274957846236552373226099112200392102883351088570736254707966329366625911183721875374731791052229266503696334310835323523568132399330263642353927504971311717117370721838701629885670598853025212521537158141447625623337563164790788106598854822686494249848796441153496412236527242235888308435573209980270776407776277489669763803746640746378181948641# c2 =4948422459907576438725352912593232312182623872749480015295307088166392790756090961680588458629287353136729331282506869598853654959933189916541367579979613191505226006688017103736659670745715837820780269669982614187726024837483992949073998289744910800139692315475427811724840888983757813069849711652177078415791290894737059610056340691753379065563574279210755232749774749757141836708161854072798697882671844015773796030086898649043727563289757423417931359190238689436180953442515869613672008678717039516723747808793079592658069533269662834322438864456440701995249381880745586708718334052938634931936240736457181295# n2 =8582505375542551134698364096640878629785534004976071646505285128223700755811329156276289439920192196962008222418309136528180402357612976316670896973298407081310073283979903409463559102445223030866575563539261326076167685019121804961393115251287057504682389257841337573435085535013992761172452417731887700665115563173984357419855481847035192853387338980937451843809282267888616833734087813693242841580644645315837196205981207827105545437201799441352173638172133698491126291396194764373021523547130703629001683366722885529834956411976212381935354905525700646776572036418453784898084635925476199878640087165680193737此题需要分别求m1和m2,先说求m1,这个是比较简单的。知道了n1,直接进行大数分解得到p和q,那求m1就是小问题了。
脚本如下:
c1 = 10004937130983861141937782436252502991050957330184611684406783226971057978666503675149401388381995491152372622456604317681236160071166819028679754762162125904637599991943368450200313304999566592294442696755822585022667008378021280392976010576970877334159755332946926433635584313137140987588847077645814987268595739733550220882135750267567373532603503399428451548677091911410732474324157868011686641243202218731844256789044721309478991918322850448456919991540932206923861653518190974620161055008847475600980152660468279765607319838003177639654115075183493029803981527882155542925959658123816315099271123470754815045214896642428657264709805029840253303446203030294879166242867850331945166255924821406218090304893024711068773287842075208409312312188560675094244318565148284432361706108491327014254387317744284876018328591380705408407853404828189643214087638328376675071962141118973835178054884474523241911240926274907256651801384433652425740230755811160476356172444327762497910600719286629420662696949923799255603628210458906831175806791599965316549386396788014703044837917283461862338269599464440202019922379625071512100821922879623930069349084917919100015782270736808388388006084027673781004085620817521378823838335749279055639005125n1 = 343504538870081878757729748260620800783581983635281373321527119223374418103340873199654926888439040391545101913132680017655039577253974802351999985470115474655124168592386965001556620077117966153475518658881140827499124290142523464795351995478153288872749817655925271395693435582010998996210909883510311066017237567799370371513462802547313382594409676803895262837061350017911885033133654781876923251129406855067993830824618637981136966134029212516871210627954762147349788788999116702635535406398258621926040887099782494271000823401788337120154104692934583729065189687995570122890809807661370008740283447636580308161498808092269041815719148127168137018600113465985504975054319601741498799761500526467431533990903047624407330243357514588557352746347337683868781554819821575385685459666842162355673947984514687068626166144076257334426612302554448774082488600083569900006274897032242821388126274957846236552373226099112200392102883351088570736254707966329366625911183721875374731791052229266503696334310835323523568132399330263642353927504971311717117370721838701629885670598853025212521537158141447625623337563164790788106598854822686494249848796441153496412236527242235888308435573209980270776407776277489669763803746640746378181948641p = 18055722101348711626577381571859114850735298658417345663254295930584841136416234624852520581982069555948490061840244710773146585295336094872892685938420880462305333393436098181186277450475949236132458958671804132443554885896037342335902958516394876382378829317303693655605215373555988755516058130500801822723195474873517960624159417903134580987202400855946137101429970119186394052011747475879598126195607938106163892658285305921071673588966184054026228745012993740035399652049777986535759039077634555909031397541116025395236871778797949216479130412500655359057128438928721459688727543057760739527720641179290282309741q = 19024691283015651666032297670418553586155390575928421823630922553034857624430114628839720683172187406577114034710093054198921843669645736474448836706112221787749688565566635453151716934583685087745112614898780150391513798368931496744574075511968933800467288441832780919514199410584786925010518564670786685241724643282580795568609339268652910564215887176803735675069372979560024792322029911970574914829712553975379661212645059271137916107885326625543090473004683836665262304916304580076748336858662108554591235698235221618061328251985929904075811056422186525179189846420226944944513865790999242309352900287977666792901phi = (p - 1) * (q - 1)d = invert(e, phi)m = pow(c1, d, n1)print(long_to_bytes(m)) #moectf{fACtord6_And_YAfu_Are_6oth_go再说求m2,由于n2是32个素数相乘得到的,想再利用n去求出p和q是比较困难的,所以得换一种思路。首先我们得先知道一个定理:当n有多个素因数时,多个素因数的欧拉与n=p*q的欧拉是一样的,故这题也可以通过大数分解,拿到那32个素因数,用32个素因数的欧拉值来代替p*q的欧拉值。
脚本如下:
c2 = 4948422459907576438725352912593232312182623872749480015295307088166392790756090961680588458629287353136729331282506869598853654959933189916541367579979613191505226006688017103736659670745715837820780269669982614187726024837483992949073998289744910800139692315475427811724840888983757813069849711652177078415791290894737059610056340691753379065563574279210755232749774749757141836708161854072798697882671844015773796030086898649043727563289757423417931359190238689436180953442515869613672008678717039516723747808793079592658069533269662834322438864456440701995249381880745586708718334052938634931936240736457181295n2 = 8582505375542551134698364096640878629785534004976071646505285128223700755811329156276289439920192196962008222418309136528180402357612976316670896973298407081310073283979903409463559102445223030866575563539261326076167685019121804961393115251287057504682389257841337573435085535013992761172452417731887700665115563173984357419855481847035192853387338980937451843809282267888616833734087813693242841580644645315837196205981207827105545437201799441352173638172133698491126291396194764373021523547130703629001683366722885529834956411976212381935354905525700646776572036418453784898084635925476199878640087165680193737primes = phi = 1for i in primes: phi *= (i - 1)d = invert(e, phi)m = pow(c2, d, n2)print(long_to_bytes(m)) #od_utils_to_fACtorize_num6ers_ff90S}n&n
源代码如下。
from Crypto.Util.number import *p = getPrime(1024)q = getPrime(1024)with open("flag.txt","r") as f: flag = f.read().strip().encode()m = bytes_to_long(flag)n = p * qe1 = 0x114514e2 = 19198101c1 = pow(m,e1,n)c2 = pow(m,e2,n)print(c1) print(c2)print(n)# 5776799746376051463605370130675046329799612910435315968508603116759552095183027263116443417343895252766060748671845650457077393391989018107887540639775168897954484319381180406512474784571389477212123123540984850033695748142755414954158933345476509573211496722528388574841686164433315356667366007165419697987147258498693175698918104120849579763098045116744389310549687579302444264316133642674648294049526615350011916160649448726069001139749604430982881450187865197137222762758538645387391379108182515717949428258503254717940765994927802512049427407583200118969062778415073135339774546277230281966880715506688898978925# 4664955020023583143415931782261983177552050757537222070347847639906354901601382630034645762990079537901659753823666851165175187728532569040809797389706253282757017586285211791297567893874606446000074515260509831946210526182765808878824360460569061258723122198792244018463880052389205906620425625708718545628429086424549277715280217165880900037900983008637302744555649467104208348070638137050458275362152816916837534704113775562356277110844168173111385779258263874552283927767924979691542028126412133709129601685315027689094437957165812994784648540588277901241854031439324974562449032290219652206466731675967045633360# 13612969130810965900902742090064423006385890357159609755971027204203418808937093492927060428980020085273603754747223030702684866992231913349067578014240319426522039068836171388168087260774376277346092066880984406890296520951318296354893551565670293486797637522297989653182109744864444697818991039473180752980752117041574628063002176339235126861152739066489620021077091941250365101779354009854706729448088217051728432010328667839532327286559570597994183126402340332924370812383312664419874352306052467284992411543921858024469098268800500500651896608097346389396273293747664441553194179933758992070398387066135330851531这题就是共模攻击了(n,m相同,c,e不同)。当n不变的情况下,知道n,e1,e2,c1,c2可以在不知道d1,d2的情况下解出m。
证明如下:
首先假设e1,e2互质,即gcd(e1,e2)=1,,此时则有e1s1+e2s2=1,其中s1,s2皆为正数,但是一正一负。通过扩展欧几里得算法,我们可以得到该式子的一组解(s1,s2),假设s1为正数,s2为负数。因为c1=m^e1 mod n,c2=m^e2 mod n,所以(c1^s1*c2^s2) mod n =((m^e1 mod n)^s1*(m^e2 mod n)^s2) mod n。根据模运算性质,可以化简为(c1^s1*c2^s2) mod n = ((m^e1)^s1*(m^e2)^s2)mod n,即(c1^s1*c2^s2) mod n = (m^(e1s1+e2s2)) mod n。前面又提到e1s1+e2s2=1,所以(c1^s1*c2^s2) mod n = m mod n,即c1^s1*c2^s2=m。脚本如下:
import gmpy2 as gpdef egcd(a, b): if a == 0: return (b, 0, 1) else: g, y, x = egcd(b % a, a) return (g, x - (b // a) * y, y)n = 13612969130810965900902742090064423006385890357159609755971027204203418808937093492927060428980020085273603754747223030702684866992231913349067578014240319426522039068836171388168087260774376277346092066880984406890296520951318296354893551565670293486797637522297989653182109744864444697818991039473180752980752117041574628063002176339235126861152739066489620021077091941250365101779354009854706729448088217051728432010328667839532327286559570597994183126402340332924370812383312664419874352306052467284992411543921858024469098268800500500651896608097346389396273293747664441553194179933758992070398387066135330851531c1 = 5776799746376051463605370130675046329799612910435315968508603116759552095183027263116443417343895252766060748671845650457077393391989018107887540639775168897954484319381180406512474784571389477212123123540984850033695748142755414954158933345476509573211496722528388574841686164433315356667366007165419697987147258498693175698918104120849579763098045116744389310549687579302444264316133642674648294049526615350011916160649448726069001139749604430982881450187865197137222762758538645387391379108182515717949428258503254717940765994927802512049427407583200118969062778415073135339774546277230281966880715506688898978925c2 = 4664955020023583143415931782261983177552050757537222070347847639906354901601382630034645762990079537901659753823666851165175187728532569040809797389706253282757017586285211791297567893874606446000074515260509831946210526182765808878824360460569061258723122198792244018463880052389205906620425625708718545628429086424549277715280217165880900037900983008637302744555649467104208348070638137050458275362152816916837534704113775562356277110844168173111385779258263874552283927767924979691542028126412133709129601685315027689094437957165812994784648540588277901241854031439324974562449032290219652206466731675967045633360e1 = 0x114514e2 = 19198101s = egcd(e1, e2)s1 = ss2 = sif s1 response.json()) .then(result => { if (result.success) { const uploadResult = document.getElementById('uploadResult'); const para = document.createElement('p'); para.textContent = ('地址:'); const link = document.createElement('a'); link.textContent = result.file_path; link.href = result.file_path; link.target = '_blank'; para.append(link); uploadResult.appendChild(para); alert('文件上传成功!'); } else { alert('文件上传失败:' + result.message); } }) .catch(error => { console.error('文件上传失败:', error); });}那就上传个图片马吧,发现上传成功了,但是不能解析。
那思路就暂时卡住了,目录扫描一下,看看有没有其他文件。没想到还真扫到个upload.php,代码如下。
代码审计:先判断了content-type类型,如果不是image/png就失败;再判断文件的大小,这个大概率不用管;然后对上传的文件名根据点号分割,如果分割完之后只有1部分,直接die;如果大于等于2部分,他只判断了第2个是不是png,那么这样子漏洞就产生了。如果我上传一个叫2.png.php的文件不就可以成功了。(我这里用的是火狐浏览器,谷歌浏览器好像抓不了localhost的包)
果然可行,并给出了上传路径,访问一下。
一看就知道,一句话木马被解析了,用蚁剑连接,获得flag。
meo图床
界面跟上题一样,考的还是文件上传漏洞。
上传一句话木马,当然是被拦截了,提示只能上传png、gif和jpeg类型的文件。
尝试了以下几种绕过方式都失败了。
第一种:上传图片马。
第二种:通过00截断上传php文件。
最终在一句话木马之前加上魔术头GIF89a后成功上传,并给出了上传路径。
发现上传之后是个php文件,直接访问想要去执行一句话木马,但是失败了。
因为url中有个name参数,猜测可能是存在任意文件读取的漏洞,随便访问一个不存在的文件。
有报错信息显示,原来是通过file_get_contents函数去读取文件的,那尝试读取一下/etc/passwd文件,成功。
既然如此,那我就直接利用这个漏洞去读flag了,根据经验大概率是藏在根目录下。
提示我们flag不在这里,但是有一个隐藏文件爆了出来。
访问一下该文件,果然有回显。
源代码如下:
就是一个简单的md5碰撞,直接利用数组绕过,读取flag成功。
夺命十三枪
访问地址,给出了源码。
一个非常明显的反序列化漏洞,但是没有看到Omg_It_Is_So_Cool_Bring_Me_My_Flag类和Deadly_Thirteen_Spears类以及其Make_a_Move方法的实现。虽然Omg_It_Is_So_Cool_Bring_Me_My_Flag的构造方法可以猜出个七七八,但是还是无法达到利用的地步。其实我们都忽略了一个点,就是开头的require_once函数,require_once函数和include_once函数最大的区别就是一个先加载再执行,一个是先执行再加载。既然这里用了require_once函数,那么说明Hanxin.exe.php文件是肯定存在的,访问一下,果不其然,源代码如下。
页:
[1]