红帽杯2021 Misc

Posted H3rmesk1t

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红帽杯2021 Misc相关的知识,希望对你有一定的参考价值。

红帽杯2021 Misc

签到

根据附件文件名EBCDIC,可知是编码问题,转换即可,这里可以采用 010 Editor

在这里插入图片描述

flag为flag{we1c0me_t0_redhat2021}

colorful code

压缩包解压后得到两个data文件,试了下找不到什么有用的东西,想到题目名字,发现文件data2用十六进制查看符合颜色的十六进制编码
这里补充一个使用颜色编写代码的知识点,该题就用到了这个点Piet

在这里插入图片描述

从图中可以看出在前面的十六进制中是没有规律可寻的,但是在后面的一段中,它却是一直递增的,这里我们没啥思路暂且先放着,看看文件data1中有什么可以用到的知识点嘛

在这里插入图片描述

发现文件data1中是0-19的数字,用空格分开,结合data2文件中前面无序后面有序,我们不妨先看看前面有些啥,将每一个字节的十六进制转换成RGB十进制,三个一组

from binascii import *

with open(r'D:\\Users\\86138\\Desktop\\RedHat\\misc\\colorful_code\\data2','rb') as f:
    f = hexlify(f.read()).decode()
    n = 0
    color_list = []
    for i in range(0,len(f),2):
        i = f[i:i+2]
        color_list.append(int(i,16))
        n += 1
        if n == 3:
            print(tuple(color_list))
            color_list = []
            n = 0
        else:
            continue
提取结果:
(0, 0, 0)
(0, 0, 192)
(0, 255, 255)
(0, 255, 0)
(255, 192, 255)
(255, 192, 192)
(192, 192, 255)
(192, 192, 0)
(255, 0, 255)
(255, 0, 0)
(192, 0, 0)
(192, 0, 192)
(255, 255, 255)
(255, 255, 0)
(255, 255, 192)
(0, 192, 0)
(0, 192, 192)
(192, 255, 255)
(192, 255, 192)
(0, 0, 255)
(20, 20, 20)
(21, 21, 21)
(22, 22, 22)
......
(253, 253, 253)
(254, 254, 254)
(255, 255, 255)

我们发现前20组数据的RGB值是无规律的,后面每一个数据的R、G、B值都一样,且依次递增到256为止
并且0-19一共也是20个数字,联想到每一个数字对应这一个颜色,我们先统计一下一共有多少个像素点

def str2list():
    with open(r'D:\\Users\\86138\\Desktop\\RedHat\\misc\\colorful_code\\data1') as f:
        f = f.read()
        index_list = f.split(' ')
        return index_list

print(len(str2list()))

统计结果显示一共有7067个像素点,我们利用质因数分解,得到图片的宽高值:
质因素分解网站

在这里插入图片描述

根据得到的值我们尝试结合宽高值对每个像素点进行putpixel()
我们先假设宽为37px,高为191px

from PIL import Image
from binascii import *

def str2list():
    with open(r'D:\\Users\\86138\\Desktop\\RedHat\\misc\\colorful_code\\data1') as f:
        f = f.read()
        index_list = f.split(' ')
        index_list = index_list[:len(index_list)-1]# 这里转换的结果最后一个是空格我们将其过滤掉
        return index_list

def num2color():
    with open(r'D:\\Users\\86138\\Desktop\\RedHat\\misc\\colorful_code\\data2','rb') as f:
        f = hexlify(f.read()).decode()
        n = 0
        idx = 0
        color_dic = {}
        color_list = []
        for i in range(0,len(f),2):
            i = f[i:i+2]
            color_list.append(int(i,16))
            n += 1
            if n == 3:
                color_dic[idx] = tuple(color_list)
                color_list = []
                n = 0
                idx += 1
            elif idx == 20:
                break
    return color_dic

def genimg():
    width, height = 37, 191
    img = Image.new("RGB",(width,height))
    imgpixels = str2list()
    colorlist = num2color()
    pixlist = []
    for pix in imgpixels:
        pixlist.append(colorlist[int(pix)])
    idx = 0
    for w in range(width):
        for h in range(height):
            img.putpixel([w,h], pixlist[idx])
            idx += 1
    img.save(r'D:\\Users\\86138\\Desktop\\RedHat\\misc\\colorful_code\\flag.png')


if __name__ == '__main__':
    genimg()

代码运行得到我们需要的flag图片
在这里插入图片描述
我们对得到图片进行piet解密,解密网站
得到最后的flag
在这里插入图片描述

flag为flag{88842f20-fb8c-45c9-ae8f-36135b6a0f11}

PicPic

压缩包打开后看到challenge就预测到了是个套娃题,我们先看看给的代码

import os
import cv2
import struct
import numpy as np


def mapping(data, down=0, up=255, tp=np.uint8):
    data_max = data.max()
    data_min = data.min()
    interval = data_max - data_min
    new_interval = up - down
    new_data = (data - data_min) * new_interval / interval + down
    new_data = new_data.astype(tp)
    return new_data


def fft(img):
    fft = np.fft.fft2(img)      
    fft = np.fft.fftshift(fft)  
    m = np.log(np.abs(fft))     
    p = np.angle(fft)           
    return m, p


if __name__ == '__main__':
    os.mkdir('m')
    os.mkdir('p')
    os.mkdir('frame')
    os.system('ffmpeg -i secret.mp4 frame/%03d.png')    #视频拆分多张照片

    files = os.listdir('frame')
    r_file = open('r', 'wb')

    for file in files:
        img = cv2.imread(f'frame/{file}', cv2.IMREAD_GRAYSCALE)     #读取所有帧

        m, p = fft(img)                                                    
        r_file.write(struct.pack('!ff', m.min(), m.max()))  

        new_img1 = mapping(m)               #绘制
        new_img2 = mapping(p)               #绘制

        cv2.imwrite(f'm/{file}', new_img1)
        cv2.imwrite(f'p/{file}', new_img2)

    r_file.close()
    os.system('ffmpeg -i m/%03d.png -r 25 -vcodec png 1.mkv')
    os.system('ffmpeg -i p/%03d.png -r 25 -vcodec png 2.mkv')

代码中把原视频做了提取帧,然后把数据接入r,把帧进行fft变换,最后合成视频,一个是频域一个是相位,结合题目给的视频,我们进行解密运算

import os
import cv2
import struct
from cv2 import data
import numpy as np
from pathlib import Path
from tqdm import trange

path = Path('.')
r = open(path/'r', 'rb')

def unmap(data, down, up):
    data_max = 255
    data_min = 0
    interval = data_max - data_min
    new_interval = up - down
    new_data = (data - data_min) * new_interval / interval + down
    return new_data

if __name__ == '__main__':
    
    os.mkdir('m')
    os.mkdir('p')
    os.mkdir('frames')
    os.system('ffmpeg -i 1.mkv m/%03d.png')
    os.system('ffmpeg -i 2.mkv p/%03d.png')

    for i in trange(200):
        filename = "%03d" % (i+1)+'.png'
        m_img = cv2.imread(str(path/'m'/filename), cv2.IMREAD_GRAYSCALE)  # mod
        p_img = cv2.imread(str(path/'p'/filename), cv2.IMREAD_GRAYSCALE)  # angle

        r_octet = r.read(8)
        m_min, m_max = struct.unpack('!ff', r_octet)

        # rev_mapping
        interval = m_max-m_min
        unmap_m = unmap(m_img,m_min,m_max)
        unmap_p = unmap(p_img,-np.pi,np.pi)

        unmap_m=np.exp(unmap_m)
        #print(old_data)
        fft = unmap_m*np.exp(1j*unmap_p)

        fft = np.fft.ifftshift(fft)
        orig_img = np.fft.ifft2(fft)

        #rint(np.abs(orig_img))

        cv2.imwrite(str(path/'frames'/filename), np.abs(orig_img))

将上述脚本放在题目文件夹下运行,得到解密后的图片

在这里插入图片描述

图片中的字符串就是压缩包next_challenge的密码:zs6hmdlq5ohav5l1
在压缩包中我们得到了challenge2和challenge3
在challenge2里面可以看见一个hint以及一个具有噪声的二维码和一个噪声,查看hint,内容为html的math标签,改后缀名为html,打开得到

在这里插入图片描述

这是相位进行了互换,幅值是不变的,所以套用公式再变换一下相位即可

import os
import cv2
import struct
import numpy as np
from PIL import Image

def fft(img):
    fft = np.fft.fft2(img)      
    fft = np.fft.fftshift(fft)  
    m = np.abs(fft)
    p = np.angle(fft)         
    return m, p

if __name__ == '__main__':
    img = np.array(Image.open(r'mix1.png').convert('L'))
    img2 = np.array(Image.open(r'mix2.png').convert('L'))
    m1, p1 = fft(img)        
    m2, p2 = fft(img2)                                            
    fft = m1*np.exp(1j*p2)      #相位转换
    fft2 = m2*np.exp(1j*p1)      #相位转换
    new_img1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fft)))             #绘制
    new_img2 = np.abs(np.fft.ifft2(np.fft.ifftshift(fft2)))                 #绘制
    #print(m)
    #print(p)
    cv2.imwrite(f'1.png', new_img1)
    cv2.imwrite(f'2.png', new_img2)

得到还原后的二维码图片

在这里插入图片描述

扫码得到一串字符串:0f88b8529ab6c0dd2b5ceefaa1c5151aa207da114831b371ddcafc74cf8701c1d3318468d50e4b1725179d1bc04b251f
应该是要让我们解密,但是缺少一些提示和东西,我们再对challenge3做类似的图像处理

import os
import cv2
import struct
import numpy as np
from PIL import Image
import math
def mapping(data, down=0, up=255, tp=np.uint8):
    data_max = data.max()
    data_min = data.min()
    interval = data_max - data_min
    new_interval = up - down
    new_data = (data - data_min) * new_interval / interval + down
    new_data = new_data.astype(tp)
    return new_data
def fft(img):
    fft = np.fft.fft2(img)
    m = np.fft.fftshift(fft)
    m = np.log(np.abs(fft))   
    return m
if __name__ == '__main__':
    img = np.array(Image.open(r'phase.png').convert('L'))
    m = mapping(img,-np.pi,np.pi,np.float64 )
    fft = np.exp(m*1j)
    p = np.fft.fftshift(fft)
    new_img1 = mapping(np.abs(np.fft.ifft2(p)))
    cv2.imwrite(f'key.png', new_img1)

得到关键词AES以及AESKEY:a8bms0v4qer3wgd67ofjhyxku5pi1czl

在这里插入图片描述

由于图片中只给出了key,故优先考虑ECB模式,解码得到flag

在这里插入图片描述

flag为flag{1ba48c8b-4eca-46aa-8216-d164538af310}

以上是关于红帽杯2021 Misc的主要内容,如果未能解决你的问题,请参考以下文章

2021第四届红帽杯网络安全大赛-线上赛Writeup

2021第四届红帽杯网络安全大赛-线上赛Writeup

第三届红帽杯线上初赛Misc题之Advertising for Marriage

红帽杯2021 Cryptography

[2021红帽杯]Web writeip

2021红帽杯 framework