Misc 题目不好评价
puzzle 二血,从早上9点看到下午3点,人已经麻了。第一次在国赛上拿到前三血,记录一下
bmp header的两个保留位不是0000,仔细观察和其他碎片的关系,猜测是碎片在原图的位置。
高度的位置比较规整,根据高度分一下碎片,然后脚本拼图
from PIL import Imageimport osimport shutilpath = ".\\tmp4" files = os.listdir(path) def combine_img (img, w, h, small_img ): width, height = small_img.size for n_w in range (width): for n_h in range (height): tmp = small_img.getpixel((n_w, n_h)) img.putpixel((w + n_w, h + n_h), tmp) for file in files: img_path = os.path.join(path, file) img = Image.open (img_path) width, height = img.size with open (img_path, "rb" ) as f: data = f.read()[6 :10 ] w_place = int (data[:2 ][::-1 ].hex (), 16 ) h_place = int (data[2 :][::-1 ].hex (), 16 ) dirs = os.listdir('.' ) tmp_dir = str (h_place) if tmp_dir not in dirs: os.mkdir(tmp_dir) shutil.copyfile(os.path.join(path, file), os.path.join(tmp_dir, str (w_place) + "_" + file)) new_img = Image.new('RGB' , (7200 , 4000 )) dirs = [str (i*100 ) for i in range (40 )] print (dirs)for dir in dirs: print (dir ) p = os.path.join('./' , dir ) files = os.listdir(os.path.join('./' , dir )) files.sort(key=lambda x: int (x.split('_' )[0 ])) for file in files: w_place = int (file.split('_' )[0 ]) h_pace = int (dir ) img = Image.open (os.path.join(p, file)) combine_img(new_img, w_place, h_pace, img) new_img.save('flag.png' )
拼好的图片发现前6行有翻转,仔细看左上角第一个碎片,明显的lsb,得到第一部分flag
flag{f1R5T_part_1s_LSB_sTeG0_
前6行翻转情况转01。根据bmp图片的biHeight,有些是9C FF FF FF,即-100,说明翻转了
BMP默认从左下角开始绘制图像,当图像高度为负数的时候,则会从左上角开始绘制图像。
import osdirs = [str (i*100 ) for i in range (6 )] for dir in dirs: res = "" p = os.path.join('./' , dir ) files = os.listdir(os.path.join('./' , dir )) files.sort(key=lambda x: int (x.split('_' )[0 ])) for file in files: img_path = os.path.join(p, file) with open (img_path, "rb" ) as f: data = f.read()[0x19 ] if (data == 255 ): res += "0" else : res += "1" print (res) ''' 001000000010000000100000001000000010000000100000001000000010000000100000 001000000011001001101110011001000101111101110000011000010101001001010100 010111110011000100110101010111110111001001100101010101100110010101010010 010100110110010101011111011000100100110101110000010111110010000000100000 001000000010000000100000001000000010000000100000001000000010111000101101 001011010010111000100000001011100010110100100000001011010010111000101110 '''
得到第二部分flag,并且还给了一个摩斯电码,提示PAD
PAD明显是提示bmp的填充里面藏了数据,bmp的一行数据需要4字节补齐。看了第一张bmp碎片的前两行,发现了填充的数据是ff d8 ff e1,jpg图片,那么脚本提取
from PIL import Imageimport osimport shutildirs = [str (i*100 ) for i in range (40 )] r = b'' start = 0x36 for dir in dirs: p = os.path.join('./' , dir ) files = os.listdir(os.path.join('./' , dir )) files.sort(key=lambda x: int (x.split('_' )[0 ])) for file in files: tmp_r = b'' img_path = os.path.join(p, file) img = Image.open (img_path) width, heigth = img.size with open (img_path, "rb" ) as f: data = f.read() tmp = width * 3 pad = 4 - (tmp % 4 ) if pad == 4 : pad = 0 gap = tmp + pad for i in range (start, len (data), gap): r += data[i + gap - pad : i + gap] with open ("1.jpg" , "wb" ) as f: f.write(r)
得到一张jpg,上面是第三部分flag
合起来得到总的flag
flag{f1R5T_part_1s_LSB_sTeG0_2nd_paRT_15_reVeRSe_bMp_3rd_parT_1s_paddINGINGING}
pyshell eval倒是没有限制,但是字符长度限制7
那么可以利用_和+来完成语句拼接
>>'open' 'open' >>_ 'open' >>_+'(' 'open(' >>_+'"/f' 'open("/f' >>_+'lag' 'open("/flag' >>_+'")' 'open("/flag")' >>_+'.re' 'open("/flag").re' >>_+'ad' 'open("/flag").read' >>_+'()' 'open("/flag").read()' >>_ 'open("/flag").read()' >>eval(_) 'flag{6eec38dd-9845-4b33-b3f4-3083fd422fc5}'
国粹 脑洞题
a.png和k.png长度一样,都是341张麻将牌,猜测一一对应,每张牌代表一个数字,一一对应组合成一个坐标,最后画图
每张牌代表的数字来自 题目.png 的顺序
from PIL import Imagedef split_img (img, w, h ): tmp_res = [] for n_w in range (53 ): for n_h in range (73 ): tmp = img.getpixel((w + n_w, h + n_h)) if len (tmp) == 4 : tmp_res.append(tmp[:-1 ]) elif len (tmp) == 3 : tmp_res.append(tmp) return tmp_res img = Image.open ("题目.png" ) width, height = img.size pic_index = [] for w in range (0 , width, 53 ): tmp_res = split_img(img, w, 0 ) pic_index.append(tmp_res) print (len (pic_index))img_a = Image.open ("a.png" ) img_k = Image.open ("k.png" ) width, height = img_a.size res = [] for w in range (0 , width, 53 ): tmp = split_img(img_a, w, 0 ) tmp1 = split_img(img_k, w, 0 ) (x, y) = (pic_index.index(tmp), pic_index.index(tmp1)) res.append((x,y)) print (len (res))new = Image.new('RGB' , (43 , 43 )) for i in res: x, y = i new.putpixel((x, y), (255 , 255 , 255 )) new.save('flag.png' )
得到
水平翻转+旋转一下
被加密的生产流量 0x03读取寄存器的word count前几个太大了,明显有问题
tshark -r modbus.pcap -T fields -e modbus.word_cnt > data.txt
流量里可以看到是几个大写字母,提出来base32一下