没报名,利益无关,a个k,图一乐
I GOT 油 我想抽 I GOT 油 ALL MY MIND 抽不了兜着走 走~走走~走走走走
Cyberspace
体力活,嗯玩游戏就行了,偷一手或或👴的图
ezdct_svd
谢罪,过于相信轮子导致我的神大人进入了误区呜呜呜,这题详细设计的dctsvd相关的隐写算法可以看一下fz的博客美团CTF-摸了摸了 – FzWjScJの菜鸡记录
俩文件,一个hint,让我见识到了新型misc出题方式
我们找到了用于嵌入水印的脚本文件hide.py中其中的三行(这三行并不挨着):
watermark = cv2.imread('qrcode.bmp', cv2.IMREAD_GRAYSCALE).flatten() > 128
block_shape = (8, 8)
Sigma[0] = (Sigma[0] // 30 + 0.5 * watermark[i] + 0.25) * 30
简单看一下关键信息,可以得知块大小为8,8,隐写算法在这,然后水印内容是把二维码二值化黑白true ,false也就是01。
知道这些了,然而没什么兴趣去了解关键的内容,所以说面对这种情况就直接进行一个google,找到了一个与其相同sigma算法的轮子。
当时以为是偷的然后直接寻思跑一下就能出,结果啪啪打脸了喵
当然这还是给予了很大的的帮助只能说
https://github.com/ShieldMnt/invisible-watermark/blob/main/imwatermark/dwtDctSvd.py
项目git下来,将关键段infer_dct_svd代码改为固定值,然后运行一下,好
原图的缩略二值图那是真牛逼。
接下来着重于对网上这个轮子的审计了,发现其在解密和加密的运算时有一些多余步骤,例如
这是没有必要的,,,结合题目给的片段也能想到不能给出这样的独立算法。所以说认为他只是单纯的dct隐写变换。
那接下来理清这个就需要知道二维码的尺寸是多长了
在之前的轮子中不断尝试使用数据可以发现最大可提取4096数据,但是结果用在代码中却不能提取出有效数据。
常见二维码长度为37*37,所以这里也进行一个测试,可以发现结果比较接近了。
64*64的效果:垃圾数据比较多,所以说上面的比较接近(确信
接下来就是对代码的修改了,对之前的轮子的独立变换代码进行删减,整合即可,最终代码
import matplotlib.pyplot as plt
import cv2
import pywt
import numpy as np
def decode(frame):
block = 8
res = []
row , col = frame.shape
for i in range(row//block):
for j in range(col//block):
block1 = np.float32(frame[i*block : i*block + block,j*block : j*block + block])
dct = cv2.dct(block1)
u,s,v = np.linalg.svd(dct)
sorce = int((s[0] % 30) > 30 * 0.5)
res.append(sorce)
return np.array(res)*255
wm_length = 37*37
pic = cv2.imread('embedded.bmp')
count = 0
R = pic[:,:,2]
r= decode(R)[:wm_length].reshape(37,37)
plt.imshow(r)
plt.show()
拿下
flag{4a8a4732-df32-415d-9945-d5ce0a16a0d1}
- 最新
- 最热
只看作者