2022祥云杯ALLMISC Writeup

第三年祥云了,从全栈做题变成只会做misc的废物了,/remake

0o0o0

一血

文件尾是pk,然后伪加密可以解开

图片[1]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

一个混淆脚本,要解混淆

from secret import o0o0o0_formula


o0000o0000 = np.float32(cv2.imread('0000.bmp', 0))
o0000o0000o = np.float32(cv2.imread('oooo.bmp', 0))
o0o0o0o0o0 = o0000o0000


for i in range(o0000o0000.shape[0]//8):  # 0-64
    for j in range(o0000o0000.shape[1]//8):  # 0-64
        o0oo000oo0 = int(o0000o0000.shape[0] / 8)
        o000000000 = int(o0000o0000.shape[1] / 8)
        o0000000000 = o0000o0000o.shape[0] * o0000o0000o.shape[1]
        o0ooooooo0 = math.ceil(o0000000000 / (o0oo000oo0 * o000000000))
        o00o0o0o00 = cv2.dct(o0000o0000[8*i:8*i+8, 8*j:8*j+8])
        for ooooooooo in range(o0ooooooo0):
            x, y = o0ooooooo0-ooooooooo, o0ooooooo0+ooooooooo
            o000ooo000 = o00o0o0o00[x, y]
            o0o0o0o0o0o = o00o0o0o00[8 - x, 8 - y]
            oo0o0 = secret([i, ooooooooo, random.randint(0, 10)])
            oo000 = secret([j, ooooooooo, random.randint(0, 10)])
            if o000ooo000 <= o0o0o0o0o0o:
                o0oo000oo0oo = random.randint(24, 36)
            else:
                o0oo000oo0oo = random.randint(-24, -12)
            o00o0o0o00[8-x, 8-y] = float(o0oo000oo0oo)
            o00o0o0o00[x, y] += float((o0000o0000o[oo0o0][oo000] - 128)*2)
        o0o0o0o0o0[8*i:8*i+8, 8*j:8*j+8] = cv2.idct(o00o0o0o00)


cv2.imwrite("0o0o0.bmp", o0o0o0o0o0)

实际上就是照着把变量换一便就行了,大概这样

import secrets
import numpy as np


img = np.float32(cv2.imread('0000.bmp', 0))
water = np.float32(cv2.imread('oooo.bmp', 0))


pic = img


for i in range(img.shape[0]//8):
    for j in range(img.shape[1]//8):
        a = int(img.shape[0] / 8)
        b = int(img.shape[1] / 8)
        num = water.shape[0] * water.shape[1]
        r = math.ceil(num / (a * b))
        dct = cv2.dct(img[8*i:8*i+8, 8*j:8*j+8])
        for m in range(r):
            rx,ry = r-m,r+m
            r1 = dct[rx,ry]
            r2 = dct[8-rx,8-ry]
            n1 = secret([i,m, random.randint(0, 10)])
            n2 = secret([i,m, random.randint(0, 10)])
            if r1<=r2:
                k = random.randint(24,36)
            else:
                k =  random.randint(-24, -12)
            
            dct[8-rx,8-ry] = float(k)
            dct[rx,ry] += float((water[m][m] - 128)*2)
        pic[8*i:8*i+8, 8*j:8*j+8] = cv2.idct(dct)
    
cv2.imwrite("0o0o0.bmp", pic)

ok,然后看看代码,

首先coploit非常牛逼,直接自动补全是dct域变换相关了,所以说这里直接也不用去想是什么算法相关了,网上脚本不太行,搜了下相关论文,还可以

一种基于DCT理论的空域数字水印算法-DAS算法 – 百度学术 (baidu.com)

然后具体更多细节内容在secert中,这里我们要结合论文内容进行分析

过一遍,r=4,然后把128的内容写入512内,之后进行8×8的分块,然后每个块需要4像素才可以全部隐藏。

计算获得

n1 = i*2+m*2

n2 = j*2+m//2

编写dct空域解密脚本

import numpy as np
import cv2 
from PIL import Image


img1 = cv2.imread('0o0o0.bmp')
img1 = img1.astype('float32')
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
w,h = 128,128


r = 4  


water = Image.new('L', (w, h), 255)


res = []


a = int(img2.shape[0] / 8)
b = int(img2.shape[1] / 8)


for i in range(a):
    for j in range(b):
        dct = cv2.dct(img2[8*i:8*i+8, 8*j:8*j+8])
        for m in range(r):
            rx,ry = 4-m,4+m
            r1 = dct[rx,ry]
            r2 = dct[7-rx,7-ry]
            if r1>r2:
                water.putpixel((i*2+m%2,j*2+m//2),0)
                res.append(0)
            else:
                water.putpixel((i*2+m%2,j*2+m//2),255)
                res.append(1)


print(res)
water.show()

获得图片

图片[2]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

读取,转ascii码,发现结果不对,尝试xor了一下0xff,获得flag

from PIL import Image


im = Image.open("water.bmp")
im = im.convert("L")
w,h = im.size
flag = []


k = 0
for i in range(h):
    for j in range(w):
        if im.getpixel((j,i)) != 255:
            k += 1
        else:
            flag.append(k)
            k = 1


for i in flag:
  print(chr(i^0xff),end="")

strange_forensics

一血

linux内存取证,基本上strings都能做,一步一步来

直接strings flag,发现了flag3

图片[3]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

flag1说是用户的密码,总所周知linux密码存在/etc/shadow文件内,当然字符串那么多也不怎么好找,还是看看,随处可见的bob

图片[4]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

那么bob也肯定就是明文存储在shadow里面了,看看shadow文件结构

图片[5]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

用户名后跟冒号加$符号,直接搜索

图片[6]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

找到了,直接丢入cmd5查询,获得flag1 890topico

然后flag2是个问题,继续寻找,尝试搜索Desktop等关键字,发现盲点,一个secret.zip的文件

图片[7]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

010搜索zip的文件头,翻到最后发现了zip文件。

图片[8]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

提取出来,是个伪解密,改下加密头00-》09进行爆破,

图片[9]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

最后获得密码123456

图片[10]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

拼接起来,最终flag

890topico_y0u_Ar3_tHe_LInUx_forEnsIcS_MASTER

补充

实际上使用vol做map解出来的捏,可惜查找文件效率实属感人,

写wp就懒得再做一遍了,strings大法好

图片[11]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

lena

水印,宇宙无敌超级大套娃,把关键内容基本都加了备注,混淆就是审计起来麻烦,其他的也没什么了,备注好各个功能就行,反正都是套娃,相互调用就行了,该题目使用的混淆工具

Oxyry Python Obfuscator – The most reliable python obfuscator in the world

import cv2
import pywt
import numpy as np
from reedsolo import RSCodec




#猫眼变换
def a(OO0O000OO00OO000O, O0O00OOOOO0OO0O0O):
    O000O0O0OOOOOO0OO, OO0000OOO0O0OOOOO, OOOOOOOOO00000OO0 = O0O00OOOOO0OO0O0O
    O0OO0OOO0OO0O0O0O = np.zeros(OO0O000OO00OO000O.shape)
    OO0OO0OOO0O0O0OOO, O00OO00OO0O000OOO = OO0O000OO00OO000O.shape[:2]
    for OOOO00O0O000O0O00 in range(O000O0O0OOOOOO0OO):
        for O0O00OO0000000000 in range(OO0OO0OOO0O0O0OOO):
            for O0OO0OO00OO0O00O0 in range(O00OO00OO0O000OOO):
                O00O00O00OOOOO000 = (O0OO0OO00OO0O00O0 +
                                     OO0000OOO0O0OOOOO * O0O00OO0000000000) % O00OO00OO0O000OOO
                OOO00000OOO0O0O00 = (
                    OOOOOOOOO00000OO0 * O0OO0OO00OO0O00O0 +
                    (OO0000OOO0O0OOOOO * OOOOOOOOO00000OO0 + 1) * O0O00OO0000000000) % OO0OO0OOO0O0O0OOO
                O0OO0OOO0OO0O0O0O[OOO00000OOO0O0O00, O00O00O00OOOOO000] = OO0O000OO00OO000O[O0O00OO0000000000,
                                                                                            O0OO0OO00OO0O00O0]
        OO0O000OO00OO000O = O0OO0OOO0OO0O0O0O.copy()
    return O0OO0OOO0OO0O0O0O


#b,分块,与c对应
def b(OO0O0OOO0OOOOOO00, O00OOOO0OOOOO0O00):
    O0OO00O00OO0OOO0O, O0O00O0O0OOOOOO0O = OO0O0OOO0OOOOOO00.shape[:2]
    OOO0000O0OOO00O0O, O0O0O0O0O0000OO00 = O00OOOO0OOOOO0O00
    OOO0OO0O00O0OO0OO = (O0OO00O00OO0OOO0O // OOO0000O0OOO00O0O, O0O00O0O0OOOOOO0O // O0O0O0O0O0000OO00,
                         OOO0000O0OOO00O0O, O0O0O0O0O0000OO00)
    O0OO0OOO0OOOO0O00 = OO0O0OOO0OOOOOO00.itemsize * np.array(
        [O0O00O0O0OOOOOO0O * OOO0000O0OOO00O0O, O0O0O0O0O0000OO00, O0O00O0O0OOOOOO0O, 1])
    OO0OO0O0OO0OO0O0O = np.lib.stride_tricks.as_strided(OO0O0OOO0OOOOOO00, OOO0OO0O00O0OO0OO,
                                                        O0OO0OOO0OOOO0O00).astype('float64')
    OO0OO0O0OO0OO0O0O = np.reshape(
        OO0OO0O0OO0OO0O0O,
        (OOO0OO0O00O0OO0OO[0] * OOO0OO0O00O0OO0OO[1], OOO0000O0OOO00O0O, O0O0O0O0O0000OO00))
    return OO0OO0O0OO0OO0O0O


#c 合块,与b对应
def c(O0O0OOOO0O0O00O0O, OOO0OO000O0000O00):
    O0O0O0O00OO0O0O00, OO000O00O0000O000 = OOO0OO000O0000O00[:2]
    OOOOO0000O0OO00OO, OOOO00O0OOO0000O0 = O0O0OOOO0O0O00O0O.shape[-2:]
    OOO0O000O0O0O00OO = (O0O0O0O00OO0O0O00 // OOOOO0000O0OO00OO, OO000O00O0000O000 // OOOO00O0OOO0000O0,
                         OOOOO0000O0OO00OO, OOOO00O0OOO0000O0)
    O0O0OOOO0O0O00O0O = np.reshape(O0O0OOOO0O0O00O0O, OOO0O000O0O0O00OO)
    OOOOO00O0O00OO00O = []
    for OO00OOO0O0O0OOO00 in O0O0OOOO0O0O00O0O:
        OOOOO00O0O00OO00O.append(np.concatenate(OO00OOO0O0O0OOO00, axis=1))
    OO00O0OO0O000OOOO = np.concatenate(OOOOO00O0O00OO00O, axis=0)
    return OO00O0OO0O000OOOO


#二值化用,
def d(OO00OOOO00000O000):
    O0O0000000000O00O = ((OO00OOOO00000O000 > 128) * 255).astype('uint8')
    return O0O0000000000O00O


#套娃变换,μ律
def e(O0OO0OOOOO0O00OOO, O000O0O0O0O00O0O0, O0OOOOOO00OO00O0O):
    return np.log(1 + O0OOOOOO00OO00O0O *
                  (np.abs(O0OO0OOOOO0O00OOO) / O000O0O0O0O00O0O0)) / np.log(1 + O0OOOOOO00OO00O0O)


#套娃里面的μ律逆变换
def f(O0O0OO0O0O000O0O0, OOOO0000O0OOOOO00, OOOO0OOO00O0OO00O):
    return (OOOO0000O0OOOOO00 / OOOO0OOO00O0OO00O) * (np.power(1 + OOOO0OOO00O0OO00O, np.abs(O0O0OO0O0O000O0O0)) - 1
                                                      )


#也是套娃的,QIM
def g(O0O0O0OO0OO00O000, O0O0O00O00000OO00, O0O0000O000OO00OO):
    O000O000OOOOO0OOO = (np.round(O0O0O0OO0OO00O000 * 1000 / O0O0000O000OO00OO) * O0O0000O000OO00OO +
                         (-1)**(O0O0O00O00000OO00 + 1) * O0O0000O000OO00OO / 4.) / 1000
    return O000O000OOOOO0OOO


class Watermark:


    def __init__(O0O0OOO0O0O000000, OO00OO0OO0OO00000):
        #初始变量定义,都是self
        O0O0OOO0O0O000000.block_shape = 4
        O0O0OOO0O0O000000.arnold_factor = (6, 20, 22)
        O0O0OOO0O0O000000.rsc_factor = 100
        O0O0OOO0O0O000000.mu_law_mu = 100
        O0O0OOO0O0O000000.mu_law_X_max = 8000
        O0O0OOO0O0O000000.delta = 15
        O0O0OOO0O0O000000.carrier = OO00OO0OO0OO00000.astype('float32')
        O00O00OOOOO0000O0, OO0OO0OO0OO0O0O0O = O0O0OOO0O0O000000.carrier.shape[:2]
        O0O0OOO0O0O000000.carrier_cA_height = O00O00OOOOO0000O0 // 2
        O0O0OOO0O0O000000.carrier_cA_width = OO0OO0OO0OO0O0O0O // 2
        O0O0OOO0O0O000000.watermark_height = O0O0OOO0O0O000000.carrier_cA_height // O0O0OOO0O0O000000.block_shape
        O0O0OOO0O0O000000.watermark_width = O0O0OOO0O0O000000.carrier_cA_width // O0O0OOO0O0O000000.block_shape
        O0O0OOO0O0O000000.max_bits_size = O0O0OOO0O0O000000.watermark_height * O0O0OOO0O0O000000.watermark_width
        O0O0OOO0O0O000000.max_bytes_size = O0O0OOO0O0O000000.max_bits_size // 8
        O0O0OOO0O0O000000.rsc_size = len(
            RSCodec(O0O0OOO0O0O000000.rsc_factor).encode(b'\x00' * O0O0OOO0O0O000000.max_bytes_size))
    #补数
    def h(OOO0O00OOOOOO0O00, O00O0OOOO00OOO0O0):
        OO00O0O0O0O0000OO = (O00O0OOOO00OOO0O0 % 2).flatten()
        if len(OO00O0O0O0O0000OO) < OOO0O00OOOOOO0O00.max_bits_size:
            OO00O0O0O0O0000OO = np.hstack(
                (OO00O0O0O0O0000OO,
                 np.zeros(OOO0O00OOOOOO0O00.max_bits_size - len(OO00O0O0O0O0000OO)))).astype('uint8')
        return OO00O0O0O0O0000OO


    #字节压缩转换
    def i(O00O0OOO0O00O0O0O, O0O0O00O00OO0O0OO):
        OOOO0OOO00O00OOOO = np.packbits(O0O0O00O00OO0O0OO).tobytes()
        return OOOO0OOO00O00OOOO


    #字节解压转换
    def j(O0O0O0O0O0O00000O, O0O00OOO00000O000):
        OOO0OOOO0O000O0OO = np.unpackbits(np.frombuffer(O0O00OOO00000O000, dtype='uint8'))
        if len(OOO0OOOO0O000O0OO) < O0O0O0O0O0O00000O.max_bits_size:
            OOO0OOOO0O000O0OO = np.hstack(
                (OOO0OOOO0O000O0OO,
                 np.zeros(O0O0O0O0O0O00000O.max_bits_size - len(OOO0OOOO0O000O0OO)))).astype('uint8')
        return OOO0OOOO0O000O0OO


    #屎山套娃...上面的efg都在里面.
    def k(OO00000O0OO0OO000, OOOOOOO00O00O0OO0, OOO00OO0O0OO0OOOO):
        O00O0OOO00OO0OO00 = OOOOOOO00O00O0OO0.copy()
        for OO000000O00OOO0O0, OO00O0000000OO0OO in enumerate(OOOOOOO00O00O0OO0):
            OO0OO0OOO0OOOOOO0 = OOO00OO0O0OO0OOOO[OO000000O00OOO0O0]
            O0OO00OO000000O0O = cv2.dct(OO00O0000000OO0OO)
            OOO000O000OO00OOO, OO00OOO000000OOO0, OO0OO0OOOO000OO0O = np.linalg.svd(O0OO00OO000000O0O)
            OO0000O0O000OO0OO = np.max(OO00OOO000000OOO0)
            OOO0O00OOOO0O0OO0 = e(OO0000O0O000OO0OO, OO00000O0OO0OO000.mu_law_X_max,
                                  OO00000O0OO0OO000.mu_law_mu)
            OOOO0OOO0O0OOO00O = g(OOO0O00OOOO0O0OO0, OO0OO0OOO0OOOOOO0, OO00000O0OO0OO000.delta)
            O00OOOOOOO0OO0OO0 = f(OOOO0OOO0O0OOO00O, OO00000O0OO0OO000.mu_law_X_max,
                                  OO00000O0OO0OO000.mu_law_mu)
            for O0O0O0OOO00O00OOO in range(OO00000O0OO0OO000.block_shape):
                if OO00OOO000000OOO0[O0O0O0OOO00O00OOO] == OO0000O0O000OO0OO:
                    OO00OOO000000OOO0[O0O0O0OOO00O00OOO] = O00OOOOOOO0OO0OO0
            O0OO0O0OOOOOO000O = np.dot(np.dot(OOO000O000OO00OOO, np.diag(OO00OOO000000OOO0)),
                                       OO0OO0OOOO000OO0O)
            O0OOO0O0O00OOO000 = cv2.idct(O0OO0O0OOOOOO000O)
            O00O0OOO00OO0OO00[OO000000O00OOO0O0] = O0OOO0O0O00OOO000
        return O00O0OOO00OO0OO00


        #关键内容,最终变换....
    def l(OOOOOOOO0OO00OOO0, O0O00O000OOO000OO):
        OOOO0O0OO0O000O00 = a(O0O00O000OOO000OO, OOOOOOOO0OO00OOO0.arnold_factor)#猫眼变换
        OOO00OO0000O0O0OO = d(OOOO0O0OO0O000O00)                                 #进行二值化
        O00O0OO0000OOOOO0 = OOOOOOOO0OO00OOO0.h(OOO00OO0000O0O0OO)              #补
        OO0000O000000O0OO = OOOOOOOO0OO00OOO0.i(O00O0OO0000OOOOO0)              #转换为字节
        OO00OOO0O0OO000OO = RSCodec(OOOOOOOO0OO00OOO0.rsc_factor)               #纠错
        O0O00OO0OO000OO0O = bytes(OO00OOO0O0OO000OO.encode(OO0000O000000O0OO)) #编码,转字节
        OOOOO0OOOOOO00OOO = OOOOOOOO0OO00OOO0.j(O0O00OO0OO000OO0O[:OOOOOOOO0OO00OOO0.max_bytes_size]) #压缩数组
        O0OO0OOO0000OO0OO = OOOOOOOO0OO00OOO0.j(O0O00OO0OO000OO0O[OOOOOOOO0OO00OOO0.max_bytes_size:])   #压缩数组
        O0OO0O00OO0000OOO = cv2.cvtColor(OOOOOOOO0OO00OOO0.carrier, cv2.COLOR_BGR2YCrCb)    #转换为YCrCb
        OOO000O00O000OO0O, OO0OO0O0OOOOOOO00, OO0OO0OO000OOO000 = cv2.split(O0OO0O00OO0000OOO)  #分离通道
        O000O00OO0O00000O, O00OO0OOO0O0OO000 = pywt.dwt2(OO0OO0O0OOOOOOO00, 'haar')      #小波变换
        O0O0O00OOOO00OO00, OOOOO00000000OO0O = pywt.dwt2(OO0OO0OO000OOO000, 'haar')         #小波变换
        OO0OOO0OOO00OO0O0 = b(O000O00OO0O00000O,
                              (OOOOOOOO0OO00OOO0.block_shape, OOOOOOOO0OO00OOO0.block_shape)) #分块
        O0OO000OOO0OO0000 = b(O0O0O00OOOO00OO00,
                              (OOOOOOOO0OO00OOO0.block_shape, OOOOOOOO0OO00OOO0.block_shape))   #分块
        O00000OO0O00O0O0O = OOOOOOOO0OO00OOO0.k(OO0OOO0OOO00OO0O0, OOOOO0OOOOOO00OOO)   #DCT套娃变换
        O000OOOO0000OOO00 = c(O00000OO0O00O0O0O,
                              (OOOOOOOO0OO00OOO0.carrier_cA_height, OOOOOOOO0OO00OOO0.carrier_cA_width)) #合块
        O0OO0O0OOO0O000OO = OOOOOOOO0OO00OOO0.k(O0OO000OOO0OO0000, O0OO0OOO0000OO0OO) #DCT套娃变换
        O000O0O0OOO00OO0O = c(O0OO0O0OOO0O000OO,
                              (OOOOOOOO0OO00OOO0.carrier_cA_height, OOOOOOOO0OO00OOO0.carrier_cA_width)) #合块
        OOO00O0OOO00OO0OO = pywt.idwt2((O000OOOO0000OOO00, O00OO0OOO0O0OO000), 'haar')  #小波逆变换
        O00OOO000O00OO0OO = pywt.idwt2((O000O0O0OOO00OO0O, OOOOO00000000OO0O), 'haar')  #小波逆变换
        O0OO000O0000000O0 = cv2.merge(
            [OOO000O00O000OO0O,
             OOO00O0OOO00OO0OO.astype('float32'),
             O00OOO000O00OO0OO.astype('float32')])
        O0OO0000000OO00O0 = cv2.cvtColor(O0OO000O0000000O0, cv2.COLOR_YCrCb2BGR) #转换为BGR
        return O0OO0000000OO00O0


if __name__ == '__main__':
    carrier = cv2.imread('test_images/lena.png')
    watermark = cv2.imread('test_images/flag.png', cv2.IMREAD_GRAYSCALE)
    wm = Watermark(carrier)
    embedded = wm.l(watermark)
    cv2.imwrite('embedded.png', embedded)

关键内容是l()函数,后面流程我都加备注了,基本流程是

两个图片各经历了不同的变化,

水印做猫眼,二值化之后压缩转为字节,最后RScode转为bytes,然后进行解压缩数据

原图首先通道转换,Cr,Cb通道进行了小波转换,随后数据分块4×4

之后将水印进行嵌入,然后使用了超级无敌大套娃的k函数(dct,svd,μ,QIM),将两组数据分别写入,Cr,Cb通道,进行合块(c函数),最终进行反小波运算,将通道转为RGB,完成隐写。。。

我只能说那是真的🐂🍺

那么知道具体思路写解密脚本就行了,就是从下往上回着写,基本都有对应,不难

脚本如下,尊重一下出题人的想法, 此处我也使用同样类型的混淆算法进行编写exp

from email.mime import image
import hashlib
import cv2
import numpy as np
import pywt
from reedsolo import RSCodec
import matplotlib.pyplot as plt


class WatermarkExtract ():
    def __init__ (O000OO00O00OOO0OO ,OOO00OO0OO0000O00 ):
        O000OO00O00OOO0OO .block_shape =4
        O000OO00O00OOO0OO .arnold_factor =(6 ,20 ,22 )
        O000OO00O00OOO0OO .rsc_factor =100 
        O000OO00O00OOO0OO .mu_law_mu =100 
        O000OO00O00OOO0OO .mu_law_X_max =8000 
        O000OO00O00OOO0OO .delta =15 
        O000OO00O00OOO0OO .carrier =OOO00OO0OO0000O00 .astype ('float32')
        O0O0O0OO0OO0OO00O ,O0OOO0O000OO0OOOO =O000OO00O00OOO0OO .carrier .shape [:2 ]
        O000OO00O00OOO0OO .carrier_cA_height =O0O0O0OO0OO0OO00O //2 
        O000OO00O00OOO0OO .carrier_cA_width =O0OOO0O000OO0OOOO //2 
        O000OO00O00OOO0OO .watermark_height =O000OO00O00OOO0OO .carrier_cA_height //O000OO00O00OOO0OO .block_shape
        O000OO00O00OOO0OO .watermark_width =O000OO00O00OOO0OO .carrier_cA_width //O000OO00O00OOO0OO .block_shape 
        O000OO00O00OOO0OO .max_bits_size =O000OO00O00OOO0OO .watermark_height *O000OO00O00OOO0OO .watermark_width
        O000OO00O00OOO0OO .max_bytes_size =O000OO00O00OOO0OO .max_bits_size //8 #line:17
        O000OO00O00OOO0OO .rsc_size =len (RSCodec (O000OO00O00OOO0OO .rsc_factor ).encode (b'\x00'*O000OO00O00OOO0OO .max_bytes_size ))
    def c (O00O000000OOOO00O ,O000O0O0OO0O0OOOO ):
        OO00O00OO00O0000O ,O00O0OOOO000O0OO0 =O000O0O0OO0O0OOOO [:2 ]#line:22
        OO0O0O0O0OOO0O000 ,OO0000OOO00O0O0O0 =O00O000000OOOO00O .shape [-2 :]#line:23
        O0000O00O0O00OO00 =(OO00O00OO00O0000O //OO0O0O0O0OOO0O000 ,O00O0OOOO000O0OO0 //OO0000OOO00O0O0O0 ,OO0O0O0O0OOO0O000 ,OO0000OOO00O0O0O0 )#line:24
        O00O000000OOOO00O =np .reshape (O00O000000OOOO00O ,O0000O00O0O00OO00 )#line:25
        O0OO00O0000OOO000 =[]#line:26
        for OO000OOOO00OO0OOO in O00O000000OOOO00O :#line:27
            O0OO00O0000OOO000 .append (np .concatenate (OO000OOOO00OO0OOO ,axis =1 ))#line:28
        O0OOO0O00O0OO0OOO =np .concatenate (O0OO00O0000OOO000 ,axis =0 )#line:29
        return O0OOO0O00O0OO0OOO #line:30
    def b (OO0000OOO000OOO00 ,O000OO000OOO0O00O ,OO0O000OO0O0OO00O ):#line:32
        OO000O000000O0OOO ,O0O00OOOO0O0O0O00 =O000OO000OOO0O00O .shape [:2 ]#line:33
        O00000OO000O0O00O ,O00000OOO0OOO00O0 =OO0O000OO0O0OO00O #line:34
        OOOOOOO0OO00OOO00 =(OO000O000000O0OOO //O00000OO000O0O00O ,O0O00OOOO0O0O0O00 //O00000OOO0OOO00O0 ,O00000OO000O0O00O ,O00000OOO0OOO00O0 )#line:35
        OO000000O0OO0OO0O =O000OO000OOO0O00O .itemsize *np .array ([O0O00OOOO0O0O0O00 *O00000OO000O0O00O ,O00000OOO0OOO00O0 ,O0O00OOOO0O0O0O00 ,1 ])#line:36
        OO00O00OOOO0OOO00 =np .lib .stride_tricks .as_strided (O000OO000OOO0O00O ,OOOOOOO0OO00OOO00 ,OO000000O0OO0OO0O ).astype ('float64')#line:37
        OO00O00OOOO0OOO00 =np .reshape (OO00O00OOOO0OOO00 ,(OOOOOOO0OO00OOO00 [0 ]*OOOOOOO0OO00OOO00 [1 ],O00000OO000O0O00O ,O00000OOO0OOO00O0 ))#line:38
        return OO00O00OOOO0OOO00 #line:39
    def e1 (O0O0O0OOO00O00000 ,OOO000O00O0OOO0O0 ,OO000OOO000OO000O ,OOOOOO00000O00O00 ):#line:43
        return np .log (1 +OOOOOO00000O00O00 *(np .abs (OOO000O00O0OOO0O0 )/OO000OOO000OO000O ))/np .log (1 +OOOOOO00000O00O00 )#line:44
    def extract (OO0OOO00OO0O00OO0 ,O000OO0O0O00OOOO0 ,OO0OOO000O000O00O ):#line:46
        return O000OO0O0O00OOOO0 /2 -OO0OOO000O000O00O *1000 %O000OO0O0O00OOOO0 #line:47
    def reverse (O0OO0OO00000000OO ,OO0O00O000000OOOO ):#line:49
        O000OOOOOOOOO0O0O =OO0O00O000000OOOO .copy ()#line:50
        O000O0OOO000OOO0O =[]#line:51
        for O0OOOOO0000O0O000 ,OOO0000OO00OO0000 in enumerate (OO0O00O000000OOOO ):#line:52
            O00OO00O00000OOOO =cv2 .dct (OOO0000OO00OO0000 )#line:53
            O00O00O0OOO0OO0O0 ,OOOO0OO0OOOOOOOOO ,O00O000OO000O0000 =np .linalg .svd (O00OO00O00000OOOO )#line:54
            O0000O0OO0000OOO0 =np .max (OOOO0OO0OOOOOOOOO )#line:55
            O00OO0OO00O00O000 =O0OO0OO00000000OO .e1 (O0000O0OO0000OOO0 ,O0OO0OO00000000OO .mu_law_X_max ,O0OO0OO00000000OO .mu_law_mu )#line:56
            O000OOOOOOOOO0O0O =O0OO0OO00000000OO .extract (O0OO0OO00000000OO .delta ,O00OO0OO00O00O000 )#line:57
            if O000OOOOOOOOO0O0O >0 :#line:58
                O000O0OOO000OOO0O .append (1 )#line:59
            else :#line:60
                O000O0OOO000OOO0O .append (0 )#line:61
        return O000O0OOO000OOO0O #line:62
    def packbits (OOO00OO00OO0OOO00 ,O0O0O00O0O00OOO00 ):#line:64
        OOO00000O00000OO0 =np .packbits (O0O0O00O0O00OOO00 ).tobytes ()#line:65
        return OOO00000O00000OO0 #line:66
    def debuffer (OO0O0OO00O000OOOO ,OOO00OOOO00O0000O ):#line:68
        O0O0O0OO00OO00OO0 =np .unpackbits (np .frombuffer (OOO00OOOO00O0000O ,dtype ='uint8'))#line:69
        return O0O0O0OO00OO00OO0 #line:70
    def dearnold (OOOO000O0OO0OOO0O ,OOOOOOO00OO0O0000 ,OOOO0O0000O0OO0OO ):#line:72
        O0OOOOOOO000OO0O0 ,O00O0OO0OO0000O00 ,OOO00O00OOO00OO00 =OOOO0O0000O0OO0OO #line:73
        OO000OO000O0000O0 ,OOOOOO0O0OOOOO00O =OOOOOOO00OO0O0000 .shape [:2 ]#line:74
        OO000OO00OOOO00O0 =np .zeros (OOOOOOO00OO0O0000 .shape )#line:75
        for O00OO00OO00O00000 in range (O0OOOOOOO000OO0O0 ):#line:76
            for O0O000000000OOO0O in range (OO000OO000O0000O0 ):#line:77
                for O0O0OOOOO0OOOOOO0 in range (OOOOOO0O0OOOOO00O ):#line:78
                    O0OO0OO0O0O0O00OO =(O0O0OOOOO0OOOOOO0 +O00O0OO0OO0000O00 *O0O000000000OOO0O )%OOOOOO0O0OOOOO00O #line:79
                    OO000OO000O0OO0O0 =(OOO00O00OOO00OO00 *O0O0OOOOO0OOOOOO0 +(O00O0OO0OO0000O00 *OOO00O00OOO00OO00 +1 )*O0O000000000OOO0O )%OO000OO000O0000O0 #line:80
                    OO000OO00OOOO00O0 [OO000OO000O0OO0O0 ,O0OO0OO0O0O0O00OO ]=OOOOOOO00OO0O0000 [O0O000000000OOO0O ,O0O0OOOOO0OOOOOO0 ]#line:81
            OOOOOOO00OO0O0000 =OO000OO00OOOO00O0 .copy ()#line:82
        return OOOOOOO00OO0O0000 #line:84
    def decode1 (OOOOOOOO0OOOO0OO0 ,O0O000OO00O0O0000 ):#line:87
        O0O000OO00O0O0000 =OOOOOOOO0OOOO0OO0 .carrier #line:88
        OOOOO0O00OOOO0O00 =cv2 .cvtColor (O0O000OO00O0O0000 ,cv2 .COLOR_BGR2YCrCb )#line:89
        OO00O0OOO00OO000O ,O0OO00OO00OOO00OO ,O00O0OOO000O0OO00 =cv2 .split (OOOOO0O00OOOO0O00 )#line:90
        O0O0OO0O0O00000O0 ,O00O0000OOOO00O0O =pywt .dwt2 (O0OO00OO00OOO00OO ,'haar')#line:92
        OO000000OOO0O0OO0 ,O0OO000OOO0OO00OO =pywt .dwt2 (O00O0OOO000O0OO00 ,'haar')#line:93
        O0O0OOO00OO0O00O0 =OOOOOOOO0OOOO0OO0 .b (O0O0OO0O0O00000O0 ,(OOOOOOOO0OOOO0OO0 .block_shape ,OOOOOOOO0OOOO0OO0 .block_shape ))#line:94
        O000OOOOO0O000O00 =OOOOOOOO0OOOO0OO0 .b (OO000000OOO0O0OO0 ,(OOOOOOOO0OOOO0OO0 .block_shape ,OOOOOOOO0OOOO0OO0 .block_shape ))#line:95
        O0O0OO00OO0OOOOOO =OOOOOOOO0OOOO0OO0 .reverse (O0O0OOO00OO0O00O0 )#line:97
        OOO00OO000OO00000 =OOOOOOOO0OOOO0OO0 .reverse (O000OOOOO0O000O00 )#line:98
        O0OOO00O000000000 =np .array (O0O0OO00OO0OOOOOO +OOO00OO000OO00000 )#line:100
        OO000OO0OOOOO00O0 =(OOOOOOOO0OOOO0OO0 .packbits (O0OOO00O000000000 ))[:OOOOOOOO0OOOO0OO0 .rsc_size ]#line:101
        OOOO0OO0OO0O0OO0O =RSCodec (OOOOOOOO0OOOO0OO0 .rsc_factor )#line:102
        OO0OOOOO00O0OOOOO =bytes (OOOO0OO0OO0O0OO0O .decode (OO000OO0OOOOO00O0 )[0 ])#line:103
        OO0000O000OOO0OOO =OOOOOOOO0OOOO0OO0 .debuffer (OO0OOOOO00O0OOOOO ).reshape ((240 ,240 ))#line:104
        for OO0O0OO0OOO00OOO0 in range (19 ):#line:105
            OO0000O000OOO0OOO =OOOOOOOO0OOOO0OO0 .dearnold (OO0000O000OOO0OOO ,OOOOOOOO0OOOO0OO0 .arnold_factor )#line:106
        return OO0000O000OOO0OOO #line:108
if __name__ =='__main__':#line:111
    embedded =cv2 .imread ('embedded.png')#line:117
    wm =WatermarkExtract (embedded )#line:118
    extart =wm .decode1 (embedded )#line:119
    cv2 .imshow ('extart',extart )#line:121
     cv2 .waitKey (0 )#line:122
图片[12]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

super_electric

misc+re+crypto 只能说re👴和密码👴是牛逼的

流量分析,MMS流量,直接追踪TCP,发现盲点

图片[13]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

一眼顶针,是MZ文件头的exe程序,仔细看一眼,是octet-string字段存储的,

然后导出csv,编写脚本即可

import csv
from hashlib import new


list1 = [] 
with open('dump.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        list1.append(row)


newlist = []


for i in range(1,len(list1)-1):
    if len(list1[i][6]) == 16:
        newlist.append(list1[i][6])


strings = ''.join(newlist)
#hex转换,保存为exe
with open('1.exe', 'wb') as f:
    f.write(bytes.fromhex(strings))

拿到文件运行发现是弹窗提示,所以直接在MessageBox下了断点回溯找到校验部分

是明文比对,所以过了第一个校验

图片[14]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

然而并没有结束,flag不对,所以在继续找程序的可疑地方即是pack段与mysec段

在pack段的有个函数CRC解密的部分,所以怀疑是个内置的压缩壳

随后经过不断调试与尝试想起start函数可疑的地方,也就是经过第一个校验之后还在运行的地方

图片[15]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

于是把程序直接跑到这,跳过去直接dump出来

图片[16]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

直接审计一下提取数据手动解密

图片[17]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

得到

data1 = [  0xEA, 0xE8, 0xE7, 0xD6, 0xDC, 0xD6, 0xEE, 0xEC, 0xFD, 0xD6, 
  0xB8, 0xFD, 0xB6]
for t in data1:
    print(chr(t ^ 0x89), end = "")


print()


data = [  0x66, 0x73, 0x6D, 0x6E, 0x24, 0x46, 0x74, 0x7E, 0x78, 0x7D, 
  0x65, 0x25, 0x4F, 0x64, 0x7E, 0x67, 0x75, 0x63, 0x32, 0x7A, 
  0x79, 0x65, 0x79, 0x65, 0x6C, 0x39, 0x5B, 0x5E, 0x4F, 0x17, 
  0x77, 0x72, 0x50, 0x4E, 0x50, 0x57, 0x04, 0x47, 0x4F, 0x49, 
  0x49, 0x5A, 0x49, 0x42, 0x45, 0x27, 0x47, 0x42, 0x40, 0x5E, 
  0x40, 0x47, 0x14, 0x5D, 0x57, 0x44, 0x50, 0x55, 0x53, 0x59, 
  0x36, 0x5B, 0x4C, 0x50, 0x2D, 0x61, 0x2A, 0x2B, 0x2C, 0x65, 
  0x2F, 0x2A, 0x38, 0x26, 0x38, 0x3F, 0x6C, 0x2B, 0x22, 0x2E, 
  0x37, 0x5B, 0x33, 0x20, 0x27, 0x30, 0x24, 0x23, 0x78, 0x3F, 
  0x36, 0x3A, 0x3B, 0x06, 0x64, 0x6A, 0x3D, 0x41, 0x5F, 0x5E, 
  0x44, 0x42, 0x00, 0x0B, 0x09, 0x0E, 0x11, 0x4C, 0x4C, 0x0C, 
  0x00, 0x0B, 0x50, 0x17, 0x1E, 0x12, 0x13, 0x2E, 0x5B, 0x46, 
  0x42, 0x24, 0x5A, 0x46, 0x41, 0x5D, 0x59, 0x02, 0xA7, 0x8B, 
  0xE9, 0xE6, 0xFD, 0xA5, 0xBB, 0xA7, 0xEA, 0xAE, 0xBE, 0xEF, 
  0xB5, 0xEC, 0xB9, 0xBF, 0xA0, 0xA1, 0xA3, 0xA3, 0xA0, 0xA6, 
  0xA1, 0xBD, 0xB2, 0xB3, 0xBD, 0x91, 0xF0, 0xBD, 0xA3, 0xBF, 
  0xCC, 0xC4, 0xCC, 0x8B, 0xCF, 0xC0, 0xDF, 0x8E, 0xA2, 0xC4, 
  0xCF, 0xD8, 0xDF, 0xCC, 0xC9, 0xCA, 0x90, 0x8C, 0x92, 0xD1, 
  0x93, 0xF1, 0xD9, 0x97, 0xC1, 0xD6, 0xCF, 0x9B, 0xD9, 0xCB, 
  0xDB, 0xCD, 0xE0, 0xA7, 0xA7, 0xA6, 0xA8, 0xE9, 0xE6, 0xA1, 
  0xAD, 0xAC, 0xA6, 0xEB, 0xBF, 0xA2, 0xEE, 0xBF, 0xB1, 0xA1, 
  0xB7, 0xA1, 0xF4, 0xA1, 0xBE, 0xBE, 0xB6, 0xF5, 0xFA, 0x97, 
  0xB5, 0xB6, 0xBB, 0xFF, 0x81, 0xC1, 0x8A, 0x8C, 0x91, 0x96, 
  0x83, 0xC7, 0x87, 0x8F, 0xCA, 0x88, 0x8D, 0x9F, 0x8A, 0x9C, 
  0xDC, 0xD1, 0xBD, 0x9D, 0x91, 0xD5, 0x94, 0x9B, 0x97, 0x8E, 
  0xDA, 0x9D, 0x8E, 0x92, 0x93, 0xDF, 0x63, 0x60, 0x74, 0x6A, 
  0x6A, 0x62, 0x26, 0x6E, 0x66, 0x2E, 0x2A, 0x20, 0x2C, 0x6F, 
  0x67, 0x61, 0x71, 0x62, 0x71, 0x7A, 0x7D, 0x3B, 0x63, 0x79, 
  0x70, 0x7C, 0x62, 0x77, 0x75, 0x7B, 0x67, 0x37, 0x48, 0x40, 
  0x51, 0x4B, 0x48, 0x4C, 0x44, 0x09, 0x5B, 0x41, 0x4B, 0x19, 
  0x19, 0x1B, 0x06, 0x44, 0x55, 0x48, 0x1B, 0x1D, 0x5C, 0x50, 
  0x4E, 0x53, 0x51, 0x5E, 0x5F, 0x48, 0x48, 0x15, 0x17, 0x16, 
  0x1B, 0x7B, 0x73, 0x73, 0x19, 0x4F, 0x2F, 0x31, 0x68, 0x74, 
  0x6A, 0x2D, 0x20, 0x2C, 0x29, 0x14, 0x65, 0x6B, 0x7F, 0x62, 
  0x09, 0x5F, 0x3B, 0x32, 0x2B, 0x2A, 0x3B, 0x3C, 0x39, 0x7D, 
  0x63, 0x7F, 0x0D, 0x04, 0x11, 0x10, 0x05, 0x02, 0x03, 0x47, 
  0x43, 0x49, 0x08, 0x12, 0x18, 0x08, 0x1D, 0x47, 0x58, 0x1D, 
  0x52, 0x5E, 0x54, 0x19, 0x13, 0x19, 0x50, 0x14, 0x1F, 0x08, 
  0x0F, 0x1C, 0x19, 0x1A, 0xA9, 0xA1, 0xA7, 0xA3, 0xE8, 0xAC, 
  0xA6, 0xAD, 0xA8, 0xEA, 0xE2, 0xF9, 0xA4, 0xE1, 0xAE, 0xA2, 
  0xB0, 0xFD, 0xF7, 0xFD, 0xBC, 0xF8, 0xF3, 0xE4, 0xEB, 0xF8, 
  0xFD, 0xFE, 0xB5, 0xBD, 0xBB, 0xBF, 0xCC, 0x88, 0x8E, 0x83, 
  0xC1, 0xCB, 0xC5, 0xC8, 0xCC, 0xC0, 0xC4, 0xCC, 0x8C, 0x90, 
  0x8E, 0x88, 0xC5, 0xC5, 0xD4, 0x9E, 0x8C, 0x92, 0x9F, 0xBD, 
  0xD9, 0xDC, 0xC9, 0x9B, 0x81, 0x9D, 0xFF, 0xFA, 0x93, 0xEF, 
  0xAC, 0xA6, 0xB3, 0xED, 0xAD, 0xA2, 0xB1, 0xE5, 0xEA, 0x8A, 
  0x89, 0x9E, 0xE0, 0x82, 0x9F, 0x95, 0x97, 0x8C, 0x97, 0x97, 
  0x95, 0xFB, 0xF8, 0xB0, 0xAC, 0xF2, 0xD6, 0xAD, 0xAC, 0xB6, 
  0x8E, 0x95, 0xCA, 0x81, 0x8D, 0x8B, 0x87, 0x94, 0x8B, 0x80, 
  0x83, 0xC5, 0x84, 0x88, 0x96, 0x83, 0x99, 0x97, 0x8B, 0xDB, 
  0x95, 0x90, 0x85, 0xD9, 0x9D, 0x97, 0x99, 0x89, 0x85, 0x8D, 
  0x8A, 0xD7, 0x6D, 0x64, 0x71, 0x70, 0x65, 0x62, 0x63, 0x2E, 
  0x21, 0x20, 0x00, 0x28, 0x26, 0x27, 0x24, 0x25, 0x3A, 0x3B, 
  0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 0x32, 0x33, 0x30, 0x31, 
  0x36, 0x37, 0x34, 0x35, 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 
  0x0C, 0x0D, 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 
  0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, 0x13, 
  0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6A, 0x6B, 0x68, 0x69, 
  0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 
  0x64, 0x65, 0x7A, 0x7B, 0x78, 0x79, 0x7E, 0x7F, 0x7C, 0x7D, 
  0x72, 0x73, 0x70, 0x71, 0x76, 0x77, 0x74, 0x75, 0x4A, 0x4B, 
  0x48, 0x49, 0x4E, 0x4F, 0x4C, 0x4D, 0x42, 0x43, 0x40, 0x41, 
  0x46, 0x47, 0x44, 0x45, 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 
  0x5C, 0x5D, 0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55, 
  0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, 0xA2, 0xA3, 
  0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, 0xBA, 0xBB, 0xB8, 0xB9, 
  0xBE, 0xBF, 0xBC, 0xBD, 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 
  0xB4, 0xB5, 0x8A, 0x8B, 0x91, 0xC5, 0xC6, 0xC4, 0x90, 0x93, 
  0xC9, 0xCD, 0x9D, 0xC9, 0x9B, 0x95, 0x98, 0x98, 0x86, 0xD4, 
  0x86, 0x85, 0x80, 0x86, 0x8F, 0x82, 0x89, 0x80, 0x83, 0x8F, 
  0x8E, 0x89, 0x8D, 0x8F, 0xF2, 0xA3, 0xF0, 0xF2, 0xA6, 0xF7, 
  0xA4, 0xF6, 0xFF, 0xAD, 0xA8, 0xF9, 0xC6]
for i in range(len(data)):
    print(chr(data[i] ^ i & 0xFF), end = "")


# can_U_get_1t?
from Crypto.Cipher import AES
import binascii
import hashlib
from hhh import flag
assert flag[:5] == 'flag{' and flag[-1:] == '}'
key = b'4d9a700010437***'
l = len(key)
message = b'Do you ever feel, feel so paper thin, Like a house of cards, One blow from caving in' + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]
iv = flag[5:-1]
message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = 'utf-8')
aes = AES.new(key, AES.MODE_CBC, iv)
print(binascii.hexlify(aes.encrypt(message)))
#******************************************************************************************************************************************************3fba64ad7b78676e464395199424302b21b2b17db2

然后又套了个密码,加点注释。

from Crypto.Cipher import AES
import binascii
import hashlib
from hhh import flag
assert flag[:5] == 'flag{' and flag[-1:] == '}'
key = b'4d9a700010437***'
l = len(key) #16
message = b'Do you ever feel, feel so paper thin, Like a house of cards, One blow from caving in' + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]
iv = flag[5:-1] #flag内容做为iv。
message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = 'utf-8')
aes = AES.new(key, AES.MODE_CBC, iv)
print(binascii.hexlify(aes.encrypt(message)))
#******************************************************************************************************************************************************3fba64ad7b78676e464395199424302b21b2b17db2



简单分析一下,首先给了个key,需要爆破,三位,然后密位没给全但是问题不大,可以用来当作校验,最后把明文当成密文来解aes应该就可以了,先爆破一下key

首先key是16进制,内容最多是0-9a-f,所以编写

from email import message
from encodings import utf_8


from Crypto.Util.number import *
from Crypto.Cipher import AES
import binascii
import hashlib


checknum =  0x3fba64ad7b78676e464395199424302b21b2b17db2


def XOR(a,b):
    c = []
    for i,j in zip(a,b):
        c.append(i^j)
    return bytes(c)
        
#16进制
strlist = "0123456789abcdef"


for a in strlist:
    for b in strlist:
        for c in strlist:
            key = '4d9a700010437'+a+b+c
            key = key.encode()
            l = len(key) #16
            message = b'Do you ever feel, feel so paper thin, Like a house of cards, One blow from caving in' + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]
            message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = 'utf-8')
            aes = AES.new(key,AES.MODE_ECB)
            data1 = long_to_bytes(checknum)
            check = data1[:-16]  #flag{
            encode= data1[-16:]  #}
            #decode
            decode = aes.decrypt(encode)[-5:]
            if check == XOR(decode,message[-5:]):
                print(key)
                break

获得key:4d9a7000104376fe

有了key之后就可以带入之前的程序继续计算就行了

#题目给的
key = "4d9a7000104376fe"
key = key.encode()
l = len(key) #16
message = b'Do you ever feel, feel so paper thin, Like a house of cards, One blow from caving in' + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]
message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = 'utf-8')
aes = AES.new(key,AES.MODE_ECB)
#clac
msg = []
for i in range(6):
    temp = message[i*16:(i+1)*16]
    msg.append(temp)


msg = msg[::-1]


flag = long_to_bytes(checknum)[-16:]
for i in range(6):
    flag = aes.decrypt(flag)
    flag = XOR(flag, msg[i])


print(flag)

BearParser

非预期上车

区块链,只给了部分代码,一直等上车来着

图片[18]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

最开始思路寻思上geth连一下看看,geth attach ip可以链上,并且使用eth.getBlock能获取其他人的交易记录,所以一直等着上车捏

图片[19]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

然后发现有队伍一血了,最速使用eth.BlockNumber查看到最新区块到了190,

图片[20]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

索性从181一直查到了190(之前区块一直在查,要么是部署,要么是转账和创建账户)直到190块发现了poc,对应一下时间刚好是一血的时间,直接复制input内容

{
  blockHash: "0xf6296217b129d81856d1edcc76be550904160f4a877cbb3ed4405789d36729e5",
  blockNumber: 190,
  from: "0xc7f0fa2a5f9a258f0762457f3e5e34ac4581dfae",
  gas: 3000000,
  gasPrice: 10000000000,
  hash: "0x5fe866a4e421c73d0c846c04e82b27830c60af842641baa606d03bd818e7550f",
  input: "0x26ad15930000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008061616161616161616161616161616161616161616161616161616161616161616262626262626262626262626262626262626262626262626262626262626262000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000001111111100000000000000000000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000278780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000006fb9eccc000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000027878000000000000000000000000000000000000000000000000000000000000",
  nonce: 0,
  r: "0x44de0f6cde5ee4144de798ac6382347bb4b8878d399f4da629e23114d1106624",
  s: "0x3c5d157b3accc627c0a95a54f6f0d2b6ca76e006e4569eada69df141c730e589",
  to: "0xf8af169b2ccde9271fdd004608c624037d58957f",
  transactionIndex: 0,
  type: "0x0",
  v: "0x4593",
  value: 0

合约随便部署个fallback() external{}

就行了然后直接to address部署题目合约,直接transact即可

图片[21]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

复制交易txhash值,最后提交

图片[22]-2022祥云杯ALLMISC Writeup-魔法少女雪殇

上车成功捏

© 版权声明
THE END
喜欢就支持一下吧
点赞24 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容