>
This site is best viewed in a modern browser with JavaScript enabled.
### id="flarum-content">
misc-和36D有点关系
yuchoxuuan
这是一入门隐写题。
为什么说入门呢?一是因为坑只有两个,而且跟上一题有承接关系,根据上一道思路容易猜到解题思路。二是两个坑都有提示。
坑1,
这个题是下载下来之后是张图片,图片的名字是LSB.png就是这么简单粗暴的告诉大家最低位隐写,不要四处抓瞎了,看本狸就是这么实诚,绝不会和别的出题人一样让大家在misc的海洋里到处乱撞。
坑1.5,既然是LSB了,那么众所周知电脑显示的图片都是RGB三个通道,那在哪个通道呢?题目没有提示,
但是,没有提示本身就是提示啊,没说那个通道,那当然是我都要了
坑 1.5.5
三个通道都要的隐藏信息可能有两种方式,一是三个通道明码存信息然后连接起来,这种方式的问题是我没告诉你连接顺序,我这么厚道的人怎么会让大家去排列组合尝试呢?所以这是不可能的;二是用三个通道的最低位通过某种计算存储一组信息,而可以接受3个运算位、可以简单还原原始信息,且符合“入门级”定位的运算是什么呢?很显然 只有异或。
所以思路有了,把每个像素红绿蓝最低位异或一下,
等你跨国第一个坑的时候,你会发现解出来的东西啥都不像,因为还有一个坑
坑2。你仔细观察照片会发现一个不协调的地方,那就是头像似乎是倒着的,对的,这其实是暗示大家,隐藏的信息是逆序灌进去的,所以你需要把坑1解出来的二进制流逆序一下,再看,你就会发现很熟悉的东西。
然后只需要把它另存成某种格式的文件,打开就可以了。
因为我的代码太烂,而且重复造了一堆奇奇怪怪的轮子,所以总是不好意思贴代码,不过有小伙伴似乎解题不太理想,所以没办法,把我的烂代码放出来吧,想笑就笑把。。。
import cv2 as cv
import numpy as np
import struct
import binascii
from PIL import Image
class FileF:
@staticmethod
def l2bf(fn='data.txt', dat=b''):
bst = b''
if isinstance(dat, str):
bst = bytes(dat, 'utf-8')
elif isinstance(dat, list):
bst = bytes(dat)
else:
bst = dat
with open(fn, 'wb') as f:
f.write(bst)
class PicBits: #像素操作
img = None
fn = ''
def __init__(self, fn=''):
try:
self.img = cv.imread(fn)
self.fn = fn
except:
pass
def show(self):
cv.imshow(self.fn, self.img)
cv.waitKey(0)
cv.destroyAllWindows()
def getxy(self, x=0,y=0):
ret = [0,0,0]
height = self.img.shape[0]
weight = self.img.shape[1]
channels = self.img.shape[2]
if x < 0 : x = -x
if y < 0 : y = -y
ret =[]
for c in range(channels):
ret.append(self.img[y%height,x%weight,c])
return ret
def setxy(self, x=0,y=0 ,col=[0,0,0]):
ret = [0,0,0]
height = self.img.shape[0]
weight = self.img.shape[1]
channels = self.img.shape[2]
if x < 0 : x = -x
if y < 0 : y = -y
self.img[y%height,x%weight] = col
def save(this,fn=''):
if fn=='':fn=this.fn
cv.imwrite(fn,this.img)
class CharF:
@staticmethod
def SplitByLen(t="", l=8, instr=" "):
if l < 1: return t
ret = ""
for i in range(len(t)):
ret += t[i]
if i % (l) == l - 1: ret += instr
while ret.startswith(instr):
ret = ret[len(instr):]
while ret.endswith(instr):
ret = ret[:-len(instr)]
return ret
@staticmethod
def str2num(txt="0", split=' ', bs=16, spl=0):
txt = txt.lower()
munl = []
if spl == 0:
numl = txt.split(split)
else:
numl = CharF.SplitByLen(txt, spl, ' ').split(' ')
retl = []
for i in numl:
try:
retl.append(int(i, bs))
except:
pass
return retl
#真正有用的就下面这几句,上面的全是我的破烂存货
def dec():
yt = PicBits('D:\\ctf\\LSB.png')
bits=""
for i in range (128):
for j in range(128):
c = yt.getxy(127-i,127-j) #逆序
bits+=chr(ord('0')+((c[0]^c[1]^c[2])&1))
l = CharF.str2num(bits,bs=2,spl=8)
FileF.l2bf('D:\\ctf\\lsb2.png',l)
dec()
condor2048
太强了,思路清奇
hdxw
所以这道题和36D有什么关系呢
yuchoxuuan
hdxw flag里面有36d
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论