几个隐写题目的总结

在几个比赛中以及网上汇总了几个隐写题目,都是关于图片的,所以为了以后的比赛可以写出一些脚本来备用,弥补stegsolve等隐写工具的不足。

第一个题目

题目是如图所示一个图片

一堆杂色,隐隐约约好像有字,看了看元数据里没啥东西,binwalk也没隐藏啥东西,改了改高度也没隐藏的信息,用Stegsolve看了看预设的几个通道,也没啥东西,估计就是在像素的低位藏了东西了吧,下面科普一下png的知识

png支持RGBA四个通道,每个通道占8个二进制位,隐写文件或数据一般都在各个通道的低位,因为低位的变化不会引起较大的视觉变化,图片还是原来的图片,但是你不知道是在哪个通道,这里有4个通道,如果藏在一个通道的低位的话,有四种可能,如果藏在两个通道的低位的话,可能进行各种运算操作后出现新的图片,加减乘除与或异或,具体的运算符也没几个,这样的话全部列举出来也不费多长时间,用python写个脚本留着以后用就好了

importcv2

importnumpy as np

importos

deflowbit(x):

returnx&0x1

png= cv2.imread("flag_enc.png" , cv2.IMREAD_UNCHANGED)

os.system("mkdirtemp")

os.system("cdtemp")

fori in range(0,4):

forf in range(0,4):

dst= cv2.bitwise_xor(lowbit(png[: ,: ,i]),lowbit(png[: ,:, f]))

cv2.imwrite("temp/"+"xor_"+str(i)+"_"+str(f)+".png",dst*255)

fori in range(0,4):

forf in range(0,4):

dst= cv2.bitwise_or(lowbit(png[: ,: ,i]),lowbit(png[: ,:, f]))

cv2.imwrite("temp/"+"or_"+str(i)+"_"+str(f)+".png",dst*255)

fori in range(0,4):

forf in range(0,4):

dst= cv2.bitwise_and(lowbit(png[: ,: ,i]),lowbit(png[: ,:, f]))

cv2.imwrite("temp/"+"and_"+str(i)+"_"+str(f)+".png",dst*255)

Stegsolve的combine功能太麻烦了,还要提取通道再运算,况且你也不知道是哪两个通道进行运算,所以我们用opencv直接提取出所有通道,暴力把所有通道的所有运算结果都生成图片,一眼就看出来了哪个有flag

第二个题目

忘了哪的题了,最后有一堆坐标,坐标,RGB之类的无非就是图片,看看最大的坐标都没超过300的,就用opencv创建画布,写进去就好了,脚本优化了一下,本来是循环300*300的画布,判断坐标是否在txt里,加上判断操作就很慢了,这里直接用numpy的ones函数创建了画布是白色的,那就循环坐标的数组改掉画布的像素就好了,运行比较快不用等

importcv2

importos

importnumpy as np

n=0

canvas= np.ones((300, 300, 3), dtype="uint8")

canvas=canvas*255

list=open("123.txt").read().split("\n")

list=[i.split(",")for i in list]

forp in list:

canvas[int(p[0]),int(p[1])]=[0,0,0]

cv2.imwrite("2.jpg",canvas)

cv2.imshow("Canvas",canvas)

cv2.waitKey(0)

扫描后得到

flag{40fc0a979f759c8892f4dc045e28b820}

第三个题目

分析数据包后得到一个txt,里面又是数字,但是这次每行是三个数字,范围从0到255之内,没有超过的,于是猜测是像素点,但是我们不知道图片的长宽就没有办法生成图片,拉到txt最下面发现是98457行,于是尝试分解质因数

即111*887,flag的话,那就是一长串字符,应该是887*111吧

import cv2

import os

import numpy as np

canvas = np.zeros((111, 887, 3), dtype="uint8")

list=open("ce.txt").read().split("\n")

for y in range(0,887):

for x in range(0,111):

arr=list[x+(y)*111].split(",")

canvas[x,y]=[arr[0],arr[1],arr[2]]

cv2.imwrite("2.jpg", canvas)

cv2.imshow("Canvas", canvas)

cv2.waitKey(0)

图片的题目们用opencv-python来写脚本解题还是很方便快捷的。图片直接是numpy数组,方便操作,也方便获取低位,直接和0x1进行按位与操作便可。