arnold图像加密(猫脸变换)
arnold图像加密(猫脸变换)
对图像中像素的坐标进行重新映射,使得图像变得杂乱无章,看起来像噪音。但过程是确定性的,有固定的公式,那么就是要考虑变换次数的问题
公式
适用于尺寸为 N x N 的图片,一般先检查图片
特性:周期性
对一张图像连续进行多次Arnold变换,当达到一个特定的次数 T(周期)时,图像会完全恢复为原始图像
代码
import numpy as np
from PIL import Imagedef arnold_decode(image, shuffle_times=10, a=13, b=14, mode='1'):image = np.array(image)decode_image = np.zeros(shape=image.shape, dtype=image.dtype)h, w = image.shape[0], image.shape[1]N = hfor _ in range(shuffle_times):for ori_x in range(h):for ori_y in range(w):new_x = ((a*b+1)*ori_x + (-b)* ori_y)% Nnew_y = ((-a)*ori_x + ori_y) % Nif mode == '1':decode_image[new_x, new_y] = image[ori_x, ori_y]else:decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]return Image.fromarray(decode_image)img = Image.open('flag.png')
decode_img = arnold_decode(img)
decode_img.save('flag-output.png')
分析一下得到的代码
import numpy as np #存储和操作图像像素数据
from PIL import Image #这个库用于打开、操作和保存多种图像格式def arnold_decode(image, shuffle_times=10, a=13, b=14, mode='1'): #mode = 1 一个模式标志,用于指示图像是黑白二值图像还是彩色图像image = np.array(image) #将image转换为 NumPy 数组,像操作矩阵一样访问和修改每个像素点的值decode_image = np.zeros(shape=image.shape, dtype=image.dtype) #创建一个所有元素都初始化为 0 的数组,确保新数组的形状和数据类型与输入图像完全相同h, w = image.shape[0], image.shape[1] #从数组的 shape 属性中提取图像的高度和宽N = h #保证宽高相同,这是arnold变换的必要条件for _ in range(shuffle_times): #控制 Arnold 变换执行的次数。shuffle_times 是函数传入的参数。_ 是一个惯例,用于表示在循环中我们不会使用到这个计数器的值for ori_x in range(h):for ori_y in range(w): #遍历每个像素ori_x 是当前像素的行坐标(从 0 到 h-1),ori_y 是列坐标(从 0 到 w-1)new_x = ((a*b+1)*ori_x + (-b)* ori_y)% Nnew_y = ((-a)*ori_x + ori_y) % N #公式运算if mode == '1':decode_image[new_x, new_y] = image[ori_x, ori_y]else:decode_image[new_x, new_y, :] = image[ori_x, ori_y, :] #处理彩色图像(如 RGB)或其他多通道图像return Image.fromarray(decode_image) #NumPy 数组转换回 PIL的Image对象img = Image.open('flag.png') #PIL的Image.open()函数打开
decode_img = arnold_decode(img) #调用上面定义的arnold_decode 函数
decode_img.save('flag-output.png')
题目
题目叫浪漫不过一次13和14
题目描述是猫眼顶真
链接: https://pan.baidu.com/s/1TPtbwOA1PIKuemrMg6vr4g 提取码: yeah
给出两个文件,其中._flag.png这个格式的文件 之前没有见过
._filename 文件格式
._filename 这种格式就是 AppleDouble 格式的文件,它专门用于在非Mac文件系统中存储Mac文件的元数据,一个具有特定二进制结构的数据文件。
该文件并不包含 flag.png 图像本身的任何像素数据。它只包含了一些Mac系统的元信息:
-
文件在Finder中使用的自定义图标。
-
文件的创建者、类型代码。
-
Spotlight 注释。
-
文件锁定的状态等。
题解
首先查看._flag.png,因为它是一个具有特定二进制结构的数据文件,那么在010editor中查看它的元数据信息,但是没有什么特别的地,都是一些图片来源的网址。
那么接下来就来观察图片flag.png。首先也是经过提示,与arnold有关,题目描述猫眼顶真(arnold 猫眼变换),且肉眼观察到flag杂乱无章,看起来像噪音,那么就考虑这个arnold图像加密,而这个类型的加密通常与变换的次数有关,再结合题目“一次13和14”,可能是变换一次,参数为13,14
那么将参数设置:shuffle_times=1, a=13, b=14
import numpy as np
from PIL import Imagedef arnold_decode(image, shuffle_times=1, a=13, b=14, mode='1'):image = np.array(image)decode_image = np.zeros(shape=image.shape, dtype=image.dtype)h, w = image.shape[0], image.shape[1]N = hfor _ in range(shuffle_times):for ori_x in range(h):for ori_y in range(w):new_x = ((a*b+1)*ori_x + (-b)* ori_y)% Nnew_y = ((-a)*ori_x + ori_y) % Nif mode == '1':decode_image[new_x, new_y] = image[ori_x, ori_y]else:decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]return Image.fromarray(decode_image)img = Image.open('/home/kali/Desktop/flag.png')
decode_img = arnold_decode(img)
decode_img.save('/home/kali/Desktop/flag-output.png')
得到了加密前的图像,直观看到了flag
但是其中走了一个弯路,但是想想来看倒也是一个可能的出题点
我通过zsteg分析图片观察到其中一个**可执行文件(mc68k executable)**的内容隐藏(嵌入) 在了这张图片的像素数据中
然后我再分析解密后得到的flag_output.png的图片
现在这个可执行文件已经不见了,大概原因估摸着是在进行像素的位置转换打乱了,导致 zsteg
无法识别其完整的文件头。
想象如果在解密图像之后flag没能以明文形式显示出来,而此时再zsteg分析得到了这个可执行文件的话那么就可以:
破解Arnold变换 -> 得到复原图 -> 用zsteg等工具提取隐藏的可执行文件 -> 逆向分析可执行文件 -> 从程序代码或内存中找到最终的flag
zsteg output.png -e b3,b,lsb,xy(选择该执行文件出现的通道) > hidden_program.bin #提取该可执行文件