当前位置: 首页 > news >正文

NSSCTF Round18 Crypto年画复现

年画

题目:

from secret import key
flag = b'NSSCTF{******FAKE*********}' 
enc_c = b''
for i in range(len(key)):enc_c += (key[i]^(flag[i%7])).to_bytes(1,'big')
print(f'enc_c={enc_c}')from PIL import Image
class Depart:def get_pixel(self, image):#打开图片image = Image.open(image)imageRGB = image.convert('RGB')#获取图片宽width=image.size[0]#获取图片高height=image.size[1]	imageBin=''for i in range(width):	for j in range(height):#遍历对应宽高的r, g, b = imageRGB.getpixel((i, j))# 将红色通道的值按8位二进制格式添加到imageBin字符串中。imageBin+='{:08b}'.format(r)# 将绿色通道的值按8位二进制格式添加到imageBin字符串中。imageBin+='{:08b}'.format(g)# 将蓝色通道的值按8位二进制格式添加到imageBin字符串中。imageBin+='{:08b}'.format(b)return imageBindef departBin(self, bin_data):#初始化一个空列表以存储分割后的二进制数据块imageBinList=[]#获取输入的二进制数据的长度。data_length=len(bin_data)#使用循环来将二进制数据分割为64位的块,直到数据长度小于64while data_length>=64:		imageBinList.append(bin_data[:64])data_length-=64bin_data=bin_data[64:]# 填充字节大小为8。if data_length == 0:# 创建一个由8位填充字节组成的填充数据padding_byte_size=8padding_data=('{:08b}'.format(padding_byte_size))*padding_byte_sizeimageBinList.append(padding_data)#对于剩余数据长度小于64的情况else:#计算需要填充的长度padding_length = 64 - data_length# 计算填充字节的大小。padding_byte_size = (padding_length)//8padding_data = ('{:08b}'.format(padding_byte_size))*padding_byte_sizeimageBinList.append(bin_data + padding_data)	return imageBinListdef make_cipher(self, imageBinList):f=open('cipher.txt','w')for i in imageBinList:f.write(i+'\n')f.close()from Crypto.Cipher import AES
from Crypto.Util.Padding import *
from PIL import Imageclass Convert:def encrypt_image(self, image_path, key):#打开图片地址image = Image.open(image_path)pixels = image.tobytes()#生成一个加密的keycipher = AES.new(key, AES.MODE_ECB)#对像素数据进行加密,使用AES密码对象加密并填充数据块。encrypted_pixels = cipher.encrypt(pad(pixels, AES.block_size))#将加密后的像素数据重新构造为图像对象。encrypted_image = Image.frombytes(image.mode, image.size, encrypted_pixels)return encrypted_imagedef run(self):image_path = "flag.png"encrypted_image = self.encrypt_image(image_path, key)encrypted_image.save("cipher.png")import random
class Same:def generate_random_image(self, image_path):cipher_image = Image.open(image_path)width, height = cipher_image.sizerandom_image = Image.new("RGB", (width, height))random_pixels = random_image.load()for x in range(width):  for y in range(height):  red = random.randint(0, 255)green = random.randint(0, 255)blue = random.randint(0, 255)random_pixels[x, y] = (red, green, blue)random_image.save("random_image.png")def drawNewYearPicture():convert = Convert()convert.run()depart = Depart()image_dir = "cipher.png"#获得图片的对应每个像素的RGB值的二进制字符串imageBinbin_data = depart.get_pixel(image_dir)imageBinList = depart.departBin(bin_data)depart.make_cipher(imageBinList)getRandom = Same()getRandom.generate_random_image(image_dir)if __name__ == '__main__':drawNewYearPicture()# enc_c=b'&2#3-(\x1e9*6"&$\x02=&'

代码审计

1.通过aes对原始图片加密-不够64位的填充
2.读取加密后图片的rgb通道值-存储在txt文件中
3.用原始图片的宽高生成新的随机图片

解题思路

1.key通过给出的enc提示对位异或还原出来
2.读取随机图片的宽高,读取txt文件还原出rgb值,填充到新图片中
3.key解密新图片 getflag

exp


def restore_bin_data(file_path):with open(file_path, 'r') as f:bin_data = f.read().replace('\n', '')  # 将所有行连接起来,并移除可能的换行符return bin_datadef restore_image_from_bin(image_bin, width, height):image = Image.new('RGB', (width, height))pixels = []# 从二进制串中获取RGB值并按列放置到二维像素列表中index = 0for i in range(width):#空列column_pixels = []for j in range(height):#提取的红色通道的值r = int(image_bin[index:index + 8], 2)#提取的红色通道的值g = int(image_bin[index + 8:index + 16], 2)#提取红色通道的值b = int(image_bin[index + 16:index + 24], 2)#将提取到的RGB值作为元组(r, g, b)添加到列的像素列表column_pixels中column_pixels.append((r, g, b))index += 24pixels.append(column_pixels)# 将二维像素列表放入图像中(按列放置)for i in range(width):for j in range(height):image.putpixel((i, j), pixels[i][j])return image
#计算key
enc_c=b'&2#3-(\x1e9*6"&$\x02=&'
key=b''
flag = b'NSSCTF{******FAKE*********}'
for i in range(len(enc_c)):key += (enc_c[i]^(flag[i%7])).to_bytes(1,'big')
print(key)
from PIL import Image#计算图片宽高
image_dir = "random_image.png"
im=Image.open(image_dir)
width =im.size[0]
height =im.size[1]# 从 "cipher.txt" 文件中恢复二进制数据
bin_data_restored = restore_bin_data('cipher.txt')
# 从二进制数据中恢复图像
restored_image = restore_image_from_bin(bin_data_restored, width, height)
restored_image.save("1.png")
image_path="1.png"
#key解密图片
from Crypto.Util.Padding import *
from Crypto.Cipher import AES
image = Image.open(image_path)
pixels = image.tobytes()
cipher = AES.new(key, AES.MODE_ECB)
#aes解码
encrypted_pixels = cipher.decrypt(pad(pixels, AES.block_size))
encrypted_image = Image.frombytes(image.mode, image.size, encrypted_pixels)
encrypted_image.show()

相关文章:

  • 【lesson53】线程控制
  • Android14之Android Rust模块编译语法(一百八十七)
  • 内网穿透 | 推荐两个免费的内网穿透工具
  • 【深度学习】S2 数学基础 P4 微积分(下)偏导数与链式法则
  • flask+python儿童福利院管理系统pycharm毕业设计项目
  • 【python】网络爬虫与信息提取--Beautiful Soup库
  • 【算法】字符串匹配算法
  • 计算机网络——11EMail
  • 移动机器人激光SLAM导航(五):Cartographer SLAM 篇
  • unity 点击事件
  • upload-labs文件上传漏洞靶场
  • VTK 三维场景的基本要素(相机) vtkCamera
  • 知识图谱 多模态学习 2024 最新综述
  • nginx限制网段访问
  • 算法沉淀——哈希算法(leetcode真题剖析)
  • 收藏网友的 源程序下载网
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 5、React组件事件详解
  • Consul Config 使用Git做版本控制的实现
  • ES学习笔记(12)--Symbol
  • express如何解决request entity too large问题
  • Javascript弹出层-初探
  • JavaScript学习总结——原型
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • MySQL用户中的%到底包不包括localhost?
  • node和express搭建代理服务器(源码)
  • XForms - 更强大的Form
  • 初探 Vue 生命周期和钩子函数
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 京东美团研发面经
  • 前端临床手札——文件上传
  • 如何实现 font-size 的响应式
  • 算法之不定期更新(一)(2018-04-12)
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 一、python与pycharm的安装
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • #ifdef 的技巧用法
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (多级缓存)缓存同步
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (篇九)MySQL常用内置函数
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (数据结构)顺序表的定义
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET DataGridView数据绑定说明
  • .Net 垃圾回收机制原理(二)
  • .NET构架之我见