「安恒杯」第二届 NEX 网络安全理论赛 WP
共解出 8 题
COMMON 【简单】签到喵 确实简单,海报下方…. …– .—- .. — ..–.- .– — .-. .—- -..摩斯电码,解码后为 H31IO_WOR1D,提交即可。(说实话第一次知道下划线怎么打)
然后,就没有 common 了。。QAQ
MATH 【简单】凯撒超进化 Vigenère cipher,这次 geekgame 也有,两种方法,一是查表,但说实话不如利用其特性可以根据 nex 这个前缀手动试出来 key 为 ozu。
【中等】2024 爱护你的蟒蛇 打开 round1.py,发现储存 flag 的部分:
1 2 3 4 5 6 7 enc = [……] def check_flag (text ): text = list (text) for i in range (len (text)): text[i] = (ord (text[i]) ^ 0xCC ) - 3 return text == enc
写出其的逆过程:
1 2 3 4 5 def de_flag (enc ): text = "" for i in range (len (enc)): text += chr ((enc[i] + 3 ) ^ 0xCC ) return text
运行得 flag。
也没了!菜死了我。
PWN 【简单】浮屠塔的出口 nc 连上之后走个迷宫就没了。
PWN 就这一题,其他的题本地打通了,然后忘了 :P
BINARY 【简单】从零开始的 CPP 生活 我不好说,但是。。。我之前为了正好装过 vs,直接打开,vs 帮我做完了。 打开 flag.cpp 后:
1 2 3 4 5 6 7 8 9 #include "flag.hpp" Flag::Flag() { flag = "flag{b9bcd94c-2ee1-4e74-b8e2-372a10869adc}" ; } std ::string Flag::GetFlag () { return this->flag; }
【中等】开源逆向题喵 打开程序,发现被挡住了,但是背景是像素字! 然后看文件,一个醒目的 flag.h,一打开,发现
1 int flag_pixels[360 ][480 ] = {……}
欸,合理怀疑就是背景 flag 图片,写转为 png 脚本:
1 2 3 4 5 6 7 8 from PIL import Imageimport numpy as npflag_pixels = [……] array = np.array(flag_pixels, dtype=np.uint8) img = Image.fromarray(array * 255 , mode='L' ) img.show()
完事,感觉不像预期解,但是有没防,怪。
【简单】假面之下的 Flag 呃呃,拖进 ida -> shift+F12 查看字串 -> 甚至第一个就是。
【困难】愤怒喵 NaN~ 我测,我一拖进 ida,main 函数那图一出来,我去,吓人。 还是 shift+F12 查看字串起手,发现两终点:
1 2 .rodata:000000000000B016 00000007 C N0N0N0 .rodata:000000000000B010 00000006 C G00D!
可以写出判断终点函数:
1 2 3 4 5 def is_success (state ): return b'G00D!' in state.posix.dumps(sys.stdout.fileno()) def is_fail (state ): return b'N0N0N0' in state.posix.dumps(sys.stdout.fileno())
这样不用记地址。 按 f5 反编分析 main 函数,发现以下语句:
1 2 stream = fopen("flag.png" , "rb" ); fread(&ptr, 1uLL , 0x142 uLL, stream);
说明读入了一个大小为 0x142 的 flag.png,可以在 angr 中模拟文件系统,创建一个 flag.png 的符号执行对象:
1 2 3 file_size = 0x142 symbolic_file = angr.storage.SimFile("flag.png" , size=file_size) initial_state.fs.insert("flag.png" , symbolic_file)
然后,跑就完事了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import angrimport sysfrom PIL import Imageimport iodef Go (): path_to_binary = "./mustangr/problem" project = angr.Project(path_to_binary) initial_state = project.factory.entry_state() file_size = 0x142 symbolic_file = angr.storage.SimFile("flag.png" , size=file_size) initial_state.fs.insert("flag.png" , symbolic_file) simulation = project.factory.simgr(initial_state) def is_success (state ): return b'G00D!' in state.posix.dumps(sys.stdout.fileno()) def is_fail (state ): return b'N0N0N0' in state.posix.dumps(sys.stdout.fileno()) simulation.explore(find=is_success, avoid=is_fail) if simulation.found: solution_state = simulation.found[0 ] flag_content = solution_state.fs.get("flag.png" ).concretize() print ("[+] Success! The flag content is: {}" .format (flag_content)) image = Image.open (io.BytesIO(flag_content)) image.save("output.png" ) else : print ("[-] Could not find the solution" ) if __name__ == "__main__" : Go()
其实 vmp 那题我也在尝试,已经打了很多函数了,但确实时间不够,没把逻辑看完 QAQ。
小结 感谢 NEX 奇妙の小题。