Flags follow the format: kashiCTF{[A-Za-z0-9_|()]}...
Créé le : 3 avril 2026
Répondu en utilisant GPT-5.4 Thinking par Chat01
Créé le : 3 avril 2026
Répondu en utilisant GPT-5.4 Thinking par Chat01
Flags follow the format: kashiCTF{[A-Za-z0-9_|()]}
giải cho đến khi tìm được flag rồi viết lại 1 file write up thật chi tiết bằng tiếng Việt
pythonfrom PIL import Image img=Image.open('/mnt/data/flag.pdf') img.mode, img.size ('RGB', (284, 150))
pythonfrom PIL import Image import numpy as np, os, matplotlib.pyplot as plt, pandas as pd, textwrap, math, itertools, collections, re, zlib, base64, struct img = Image.open('/mnt/data/flag.pdf') arr = np.array(img) arr.shape, arr.min(), arr.max(), arr.mean() ((150, 284, 3), np.uint8(0), np.uint8(255), np.float64(211.19287949921753))
pythonfor c,name in enumerate('RGB'): vals=arr[:,:,c].flatten() print(name, len(np.unique(vals)), vals.min(), vals.max(), vals.mean(), vals.std())
pythonfrom PIL import Image import numpy as np, os img = Image.open('/mnt/data/flag.pdf').convert('RGB') arr = np.array(img) outdir='/mnt/data/bitplanes' os.makedirs(outdir, exist_ok=True) for c,name in enumerate('RGB'): for b in range(8): plane=((arr[:,:,c]>>b)&1)*255 Image.fromarray(plane.astype('uint8')).save(f'{outdir}/{name}_bit{b}.png') print(outdir)
pythonfrom PIL import Image, ImageOps, ImageDraw import os, math paths=[f'/mnt/data/bitplanes/{c}_bit{b}.png' for c in 'RGB' for b in range(7,-1,-1)] ims=[Image.open(p).convert('L').resize((284,150)) for p in paths] labels=[os.path.basename(p).replace('.png','') for p in paths] w,h=ims[0].size sheet=Image.new('RGB',(w*4,h*6),(255,255,255)) draw=ImageDraw.Draw(sheet) for i,(im,label) in enumerate(zip(ims,labels)): x=(i%4)*w y=(i//4)*h sheet.paste(Image.merge('RGB',(im,im,im)),(x,y)) draw.rectangle([x,y,x+80,y+15],fill=(255,255,255)) draw.text((x+2,y+2),label,fill=(255,0,0)) sheet.save('/mnt/data/bitplanes_sheet.png
pythonfrom PIL import Image, ImageOps, ImageDraw import os, math paths=[f'/mnt/data/bitplanes/{c}_bit{b}.png' for c in 'RGB' for b in range(7,-1,-1)] ims=[Image.open(p).convert('L').resize((284,150)) for p in paths] labels=[os.path.basename(p).replace('.png','') for p in paths] w,h=ims[0].size sheet=Image.new('RGB',(w*4,h*6),(255,255,255)) draw=ImageDraw.Draw(sheet) for i,(im,label) in enumerate(zip(ims,labels)): x=(i%4)*w y=(i//4)*h sheet.paste(Image.merge('RGB',(im,im,im)),(x,y)) draw.rectangle([x,y,x+80,y+15],fill=(255,255,255)) draw.text((x+2,y+2),label,fill=(255,0,0)) sheet.save('/mnt/data/bitplanes_sheet.png <<ImageDisplayed>>
pythonimport os, math, collections, re, struct, zlib, bz2, lzma, gzip, base64, binascii, hashlib data=open('/mnt/data/flag_tail.bin','rb').read() len(data), data[:16], data[-16:] (29820, b'\xff\xff\xfb\xff\xff\xfb\xff\xff\xfb\xff\xff\xfb\xff\xff\xfb\xff', b'\xff\xfe\xff\xfd\xfe\xff\xff\xfe\xff\xfd\xfe\xff\xff\xfe\xff\xfd')
pythonfrom PIL import Image data=open('/mnt/data/flag.pdf','rb').read() header=b'P6\n284 150\n255\n' assert data.startswith(header) pix=data[len(header):] len(pix), 284*185*3 (157620, 157620)
pythonfrom PIL import Image import numpy as np data=open('/mnt/data/flag.pdf','rb').read() header=b'P6\n284 150\n255\n' pix=data[len(header):] img = Image.frombytes('RGB', (284,185), pix) img.save('/mnt/data/flag_full.png') print('/mnt/data/flag_full.png')
pythonfrom PIL import Image import numpy as np data=open('/mnt/data/flag.pdf','rb').read() header=b'P6\n284 150\n255\n' pix=data[len(header):] img = Image.frombytes('RGB', (284,185), pix) img.save('/mnt/data/flag_full.png') print('/mnt/data/flag_full.png') <<ImageDisplayed>>
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob, math files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) ims=[Image.open(f).convert('RGB') for f in files] # resize thumbnails thumbs=[] for i,im in enumerate(ims): im.thumbnail((380,540)) canvas=Image.new('RGB',(400,560),'white') canvas.paste(im,((400-im.width)//2,20)) d=ImageDraw.Draw(canvas) d.text((10,5),os.path.basename(files[i]),fill='black') thumbs.append(canvas) sheet=Image.new('RGB',(800,1120),'#dddddd') for idx,im in enumerate(thumbs): x=(idx%2)*400 y=(idx//2)*560 sheet.paste(im,(x,y)) sheet.save('/mnt/data/writeup_sheet.png') print('/mnt/data/writeup_sheet.png')
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob, math files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) ims=[Image.open(f).convert('RGB') for f in files] # resize thumbnails thumbs=[] for i,im in enumerate(ims): im.thumbnail((380,540)) canvas=Image.new('RGB',(400,560),'white') canvas.paste(im,((400-im.width)//2,20)) d=ImageDraw.Draw(canvas) d.text((10,5),os.path.basename(files[i]),fill='black') thumbs.append(canvas) sheet=Image.new('RGB',(800,1120),'#dddddd') for idx,im in enumerate(thumbs): x=(idx%2)*400 y=(idx//2)*560 sheet.paste(im,(x,y)) sheet.save('/mnt/data/writeup_sheet.png') print('/mnt/data/writeup_sheet.png') <<ImageDisplayed>>
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) len(files) 4
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob, math files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) ims=[Image.open(f).convert('RGB') for f in files] thumbs=[] for i,im in enumerate(ims): im.thumbnail((380,540)) canvas=Image.new('RGB',(400,560),'white') canvas.paste(im,((400-im.width)//2,20)) d=ImageDraw.Draw(canvas) d.text((10,5),os.path.basename(files[i]),fill='black') thumbs.append(canvas) sheet=Image.new('RGB',(800,1120),'#dddddd') for idx,im in enumerate(thumbs): x=(idx%2)*400 y=(idx//2)*560 sheet.paste(im,(x,y)) sheet.save('/mnt/data/writeup_sheet2.png') print('/mnt/data/writeup_sheet2.png')
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob, math files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) ims=[Image.open(f).convert('RGB') for f in files] thumbs=[] for i,im in enumerate(ims): im.thumbnail((380,540)) canvas=Image.new('RGB',(400,560),'white') canvas.paste(im,((400-im.width)//2,20)) d=ImageDraw.Draw(canvas) d.text((10,5),os.path.basename(files[i]),fill='black') thumbs.append(canvas) sheet=Image.new('RGB',(800,1120),'#dddddd') for idx,im in enumerate(thumbs): x=(idx%2)*400 y=(idx//2)*560 sheet.paste(im,(x,y)) sheet.save('/mnt/data/writeup_sheet2.png') print('/mnt/data/writeup_sheet2.png') <<ImageDisplayed>>
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) len(files), files (4, ['/mnt/data/writeup_render/page-1.png', '/mnt/data/writeup_render/page-2.png', '/mnt/data/writeup_render/page-3.png', '/mnt/data/writeup_render/page-4.png'])
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob, math files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) ims=[Image.open(f).convert('RGB') for f in files] thumbs=[] for i,im in enumerate(ims): im.thumbnail((380,540)) canvas=Image.new('RGB',(400,560),'white') canvas.paste(im,((400-im.width)//2,20)) d=ImageDraw.Draw(canvas) d.text((10,5),os.path.basename(files[i]),fill='black') thumbs.append(canvas) sheet=Image.new('RGB',(800,1120),'#dddddd') for idx,im in enumerate(thumbs): x=(idx%2)*400 y=(idx//2)*560 sheet.paste(im,(x,y)) sheet.save('/mnt/data/writeup_sheet3.png') print('/mnt/data/writeup_sheet3.png')
pythonfrom PIL import Image, ImageOps, ImageDraw import os, glob, math files=sorted(glob.glob('/mnt/data/writeup_render/page-*.png')) ims=[Image.open(f).convert('RGB') for f in files] thumbs=[] for i,im in enumerate(ims): im.thumbnail((380,540)) canvas=Image.new('RGB',(400,560),'white') canvas.paste(im,((400-im.width)//2,20)) d=ImageDraw.Draw(canvas) d.text((10,5),os.path.basename(files[i]),fill='black') thumbs.append(canvas) sheet=Image.new('RGB',(800,1120),'#dddddd') for idx,im in enumerate(thumbs): x=(idx%2)*400 y=(idx//2)*560 sheet.paste(im,(x,y)) sheet.save('/mnt/data/writeup_sheet3.png') print('/mnt/data/writeup_sheet3.png') <<ImageDisplayed>>
Đã tìm được flag:
kashiCTF{iLOVEkashi}
Mấu chốt là file flag.pdf thực ra không phải PDF mà là ảnh PPM bị đổi đuôi, và phần header đã bị sửa chiều cao từ 185 xuống 150 để che 35 dòng pixel cuối. Khi dựng lại ảnh với kích thước đúng, flag hiện ra ở mép dưới.
File write-up tiếng Việt chi tiết: Download write-up DOCX
Ảnh đã khôi phục: Recovered image