CTF | 2021 春秋杯 Baby_steg WriteUp


引言

2021年 春秋杯 网络安全联赛春季赛

比赛时间:2021年5月29日 10:00-18:00

https://www.ichunqiu.com/chunqiucup

和上一篇一样,这周末比赛巨多。

于是春秋杯的话也是随意看了题,然而发现题目挺难的 Orz。

这个比赛的时候就摸鱼做了 Misc Baby_steg 题目的一半,剩下一半还是比赛后复现的。其他题目就没怎么看吧。

这题结合了几个之前没见过的玩法,这里顺手记录一下。

Baby_steg

小A想学MISC,她请教了某大佬,大佬为了考验她的能力,给了她一个文件,让她找到其中隐藏的秘密,可是小A拿到文件后一脸懵逼,所以来找你求救,你能帮助她吗?

附件下载 提取码(GAME)备用下载

hint:先获取password.7z里面的内容,大佬好像跟小A说是6-8位的数字

下载下来个压缩包。

根据提示需要先解密那个 7z。

搜了一下发现 cRARk for 7-Zip 用来爆破还挺不错,支持自定义各种格式的密码,还能调用 GPU 加速运算。

https://www.crark.net/crark-7zip.html 这里下载。

参考 https://www.crark.net/cRARk-7z.htmlpassword.def 定义文件。

由于全是数字,直接就写成这样。

##
$1 *

然后指定最小和最大的长度去解密。

crark-7z.exe -l6 -g8 password.7z

得到 7z 的密码 321456

解压出来个 password.txt

7324623c

flag1.txt 这是什么玩意……

后来看了别人 wp 才发现是 uuencode。来复现一下。

拿 python 写个脚本解码一下。

import uu
s = uu.decode('flag1.txt')

它会自动输出文件。

加密的话就是

uu.encode(input_file, output_file)

用上面解密得到的 7324623c 作为密码解压。

得到一张图 challenge.png

challenge

以及 encode.py

import numpy as np
import cv2
import sys
import random

def encode(image):
    i = random.randint(520,540)
    np.random.seed(i)
    # image = 1298 * 695
    to_hide = cv2.imread(image)
    to_hide_array = np.asarray(to_hide)

    for i in range(to_hide_array.shape[0]):
        np.random.shuffle(to_hide_array[i])
    
    gray = cv2.cvtColor(to_hide_array, cv2.COLOR_BGR2GRAY)
    cv2.imwrite('challenge.png', gray)
    print("encode!")

def main():
    if len(sys.argv) != 2:
        print('error!')
        exit(1)
    encode(sys.argv[1])

if __name__ == '__main__':
    main()

随机数种子在 520-540 之前取值,np.random.shuffle 函数把 to_hide_array 第1个维度上的数字进行位置上的随机打乱。

于是可以试试爆破这个随机数种子,记录下打乱前后下标的映射关系,再反过来恢复出原始图像,其中一个就是打乱之前的图像了。

另外注意 random.randint(520,540) 在 520 和 540 上都能取到值,即左右区间都闭合。

代码写的有点乱,能用就行了。(逃走

import numpy as np
import cv2
import sys
import random


def decode(image):
    # image = 1298 * 695
    to_hide = cv2.imread(image)
    to_hide_array = np.asarray(to_hide)
    shape = to_hide_array.shape

    for i in range(520, 541):
        print('====>', i)
        np.random.seed(i)
        l1 = []
        for j in range(shape[0]):
            l2 = list(range(shape[1]))
            new_array = []
            np.random.shuffle(l2)
            for x in range(len(l2)):
                new_array.append(to_hide_array[j][l2.index(x)])
            l1.append(new_array)
        l1_array = np.asarray(l1)
        # gray = cv2.cvtColor(l1_array, cv2.COLOR_BGR2GRAY)
        cv2.imwrite(f'decode{i}.png', l1_array)


def main():
    decode('challenge.png')


if __name__ == '__main__':
    main()

最后跑出来是随机种子为 540 时候的情况,得出 flag。

decode540

小结

Baby_steg 这题还是堆了几个没玩过的知识点的,正好还把 7z 压缩包爆破的工具也找了一波,cRARk for 7-Zip 还是挺香的!

顺便还发现了 python 里的 uu 就能直接进行 uuencode 编解码,好耶。

就这样吧,摸🐟大法好!

BTW,XCTF final 的题目太顶了,喵喵好菜玩不来,喵呜呜呜。

(看啥时候有机会再摸鱼来复现吧,喵喵🐱

(溜了溜了喵


文章作者: MiaoTony
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 MiaoTony !
评论
  目录