buuctf[安洵杯 2019]easy misc1

解压的一个文件夹和图片一个,zip压缩包有密码

FLAG IN ((√2524921X85÷5+2)÷15-1794)+NNULLULL,

((√2524921X85÷5+2)÷15-1794)=7

我用passware kit 2022 所以试试7位数字+NNULLULL,掩码(mask)攻击试试

mask :?d?d?d?d?d?d?dNNULLULL?s

好多破解方式,节省时间,就不一一尝试了,点all全删除

点+把mask攻击按下图添加

用这个密码2019456NNULLULL,解压得

010editor打开小姐姐图片发现两个图片结尾,去kali分离图片

为了方便输入改名1.png和2.png

用Stegsolve查看发现有盲水印

sudo pip install blind-watermark

如果在使用blind - watermark提取水印时没有密码,对于1.png,你可以尝试以下命令(假设水印为文本水印,并且嵌入时没有使用特殊参数设置水印形状等复杂情况):

blind_watermark --extract 1.png

对于2.png

blind_watermark --extract 2.png


  • 对于WaterMark类初始化部分(在/usr/local/lib/python3.11/dist - packages/blind_watermark/cli_tools.py文件中),修改密码参数的处理逻辑。
  • 如果目的是允许空密码,可以修改代码,在将密码转换为整数之前,先判断密码是否为None,如果是None,则可以传递一个默认值(例如 0 或者其他预定义的表示空密码的值)。
     def main():
         if opts.password is None:
             opts.password = 0
         bwm1 = WaterMark(password_img = int(opts.password))
         # 后续代码...

虽然解了但是乱码。采用其他工具提取,去github 找到python脚本

https://github.com/chishaxie/BlindWaterMark

GitCode - 全球开发者的开源社区,开源代码托管平台

我使用anaconda 创建一个虚拟环境,依次在conda命令窗口输入以下命令

conda create -n mangshuiyin python=3.6

conda activate mangshuiyin

pip install opencv-python==4.2.0.34  -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install matplotlib==2.1.1  -i https://pypi.tuna.tsinghua.edu.cn/simple

切换到脚本所在目录

cd D:\tools\BlindWaterMark-master\BlindWaterMark-master      

python bwmforpy3.py decode 1.png  2.png ras.png --oldseed

修改 bwmforpy3.py 添加红框内容

题外话:这个盲水印脚本较为老旧,参照作者思路,我更新了脚本,可以适配更高版本python和opencv-python、matplotlib库。

#!/usr/bin/env python
# -*- coding: utf8 -*-

import sys
import random
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os


def bgr_to_rgb(img):
    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)


def main():
    # 初始化变量
    debug = False
    seed = 20160930
    oldseed = False
    alpha = 3.0

    # 处理命令行参数
    args = sys.argv[1:]
    if '-h' in args or '--help' in args or len(args) < 2:
        print('Usage: python bwm.py <cmd> <image1> <image2> <image3> [opts...]')
        print('  cmds:')
        print('    encode <image> <watermark> <image(encoded)>')
        print('           image + watermark -> image(encoded)')
        print('    decode <image> <image(encoded)> <watermark>')
        print('           image + image(encoded) -> watermark')
        print('  opts:')
        print('    --debug,          Show debug')
        print('    --seed <int>,     Manual setting random seed (default is 20160930)')
        print('    --oldseed         Use python2 random algorithm.')
        print('    --alpha <float>,  Manual setting alpha (default is 3.0)')
        sys.exit(1)

    cmd = args[0]
    if cmd not in ['encode', 'decode']:
        print('Wrong cmd %s' % cmd)
        sys.exit(1)

    image_args = args[1:4]
    if len(image_args) < 3:
        print('Missing arg...')
        sys.exit(1)

    opt_args = args[4:]
    for arg in opt_args:
        if arg == '--debug':
            debug = True
        elif arg == '--seed':
            try:
                index = opt_args.index(arg) + 1
                seed = int(opt_args[index])
            except (IndexError, ValueError):
                print('Missing <int> for --seed')
                sys.exit(1)
        elif arg == '--oldseed':
            oldseed = True
        elif arg == '--alpha':
            try:
                index = opt_args.index(arg) + 1
                alpha = float(opt_args[index])
            except (IndexError, ValueError):
                print('Missing <float> for --alpha')
                sys.exit(1)

    fn1, fn2, fn3 = image_args

    if cmd == 'encode':
        print('image<%s> + watermark<%s> -> image(encoded)<%s>' % (fn1, fn2, fn3))
        img = cv2.imread(fn1)
        if img is None:
            print(f"Error reading image {fn1}")
            sys.exit(1)
        else:
            print(f"Image {fn1} read successfully. Shape: {img.shape}")
        wm = cv2.imread(fn2)
        if wm is None:
            print(f"Error reading watermark image {fn2}")
            sys.exit(1)
        else:
            print(f"Watermark image {fn2} read successfully. Shape: {wm.shape}")

        if debug:
            plt.subplot(231), plt.imshow(bgr_to_rgb(img)), plt.title('image')
            plt.xticks([]), plt.yticks([])
            plt.subplot(234), plt.imshow(bgr_to_rgb(wm)), plt.title('watermark')
            plt.xticks([]), plt.yticks([])

        h, w = img.shape[:2]
        # 修改后的hwm构建
        hwm = np.zeros((int(h * 0.5), w, img.shape[2]))
        hwm2 = np.copy(hwm)
        for i in range(wm.shape[0]):
            for j in range(wm.shape[1]):
                hwm2[i][j] = wm[i][j]
        if oldseed:
            random.seed(seed, version=1)
            m = list(range(hwm.shape[0]))
            n = list(range(hwm.shape[1]))
            random.shuffle(m, random=random.random)
            random.shuffle(n, random=random.random)
        else:
            random.seed(seed)
            m = list(range(hwm.shape[0]))
            n = list(range(hwm.shape[1]))
            random.shuffle(m)
            random.shuffle(n)
        for i in range(hwm.shape[0]):
            for j in range(hwm.shape[1]):
                hwm[i][j] = hwm2[m[i]][n[j]]
        print("hwm after embedding watermark: ", hwm)

        rwm = np.zeros_like(img)
        rwm[:hwm.shape[0], :hwm.shape[1]] = hwm
        rwm[-hwm.shape[0]:, -hwm.shape[1]:] = hwm

        if debug:
            plt.subplot(235), plt.imshow(bgr_to_rgb(rwm)), \
                plt.title('encrypted(watermark)')
            plt.xticks([]), plt.yticks([])

        # 修改后的f1计算及后续操作
        f1 = np.fft.fft2(img)
        f2 = f1 + alpha * rwm
        _img = np.fft.ifft2(f2)
        img_wm = np.real(_img)

        if not cv2.imwrite(fn3, img_wm, [int(cv2.IMWRITE_JPEG_QUALITY), 100]):
            print(f"Error saving file {fn3}")

        img_wm2 = cv2.imread(fn3)
        if img_wm2 is None:
            print(f"Error reading encoded image {fn3}")
            sys.exit(1)
        else:
            print(f"Encoded image {fn3} read successfully. Shape: {img_wm2.shape}")
        img_wm = np.array(img_wm, dtype=np.float64)
        img_wm2 = np.array(img_wm2, dtype=np.float64)
        miss = np.linalg.norm(img_wm - img_wm2) / np.linalg.norm(img_wm) * 100
        print('Miss %s%% in save' % miss)

        if debug:
            plt.subplot(233), plt.imshow(bgr_to_rgb(np.uint8(img_wm))), \
                plt.title('image(encoded)')
            plt.xticks([]), plt.yticks([])

        f2 = np.fft.fft2(img_wm)
        rwm = (f2 - f1) / alpha
        rwm = np.real(rwm)

        wm = np.zeros_like(rwm)
        wm[:int(rwm.shape[0] * 0.5), :rwm.shape[1]] = rwm[:int(rwm.shape[0] * 0.5), :rwm.shape[1]].astype(np.uint8)
        wm[-int(rwm.shape[0] * 0.5):, -rwm.shape[1]:] = wm[:int(rwm.shape[0] * 0.5), :rwm.shape[1]]

        if debug:
            if not cv2.imwrite('_bwm.debug.wm.jpg', wm.astype(np.uint8)):
                print(f"Error saving debug watermark file _bwm.debug.wm.jpg")
            plt.subplot(236), plt.imshow(bgr_to_rgb(wm)), plt.title('watermark')
            plt.xticks([]), plt.yticks([])

        if debug:
            plt.show()

    elif cmd == 'decode':
        print('image<%s> + image(encoded)<%s> -> watermark<%s>' % (fn1, fn2, fn3))
        img = cv2.imread(fn1)
        if img is None:
            print(f"Error reading image {fn1}")
            sys.exit(1)
        else:
            print(f"Image {fn1} read successfully. Shape: {img.shape}")
        img_wm = cv2.imread(fn2)
        if img_wm is None:
            print(f"Error reading encoded image {fn2}")
            sys.exit(1)
        else:
            print(f"Encoded image {fn2} read successfully. Shape: {img_wm.shape}")

        if debug:
            plt.subplot(231), plt.imshow(bgr_to_rgb(img)), plt.title('image')
            plt.xticks([]), plt.yticks([])
            plt.subplot(234), plt.imshow(bgr_to_rgb(img_wm)), plt.title('image(encoded)')
            plt.xticks([]), plt.yticks([])

        if oldseed:
            random.seed(seed, version=1)
            m = list(range(int(img.shape[0] * 0.5)))
            n = list(range(img.shape[1]))
            random.shuffle(m, random=random.random)
            random.shuffle(n, random=random.random)
        else:
            random.seed(seed)
            m = list(range(int(img.shape[0] * 0.5)))
            n = list(range(img.shape[1]))
            random.shuffle(m)
            random.shuffle(n)

        f1 = np.fft.fft2(img)
        f2 = np.fft.fft2(img_wm)

        if debug:
            plt.subplot(232), plt.imshow(bgr_to_rgb(np.real(f1))), \
                plt.title('fft(image)')
            plt.xticks([]), plt.yticks([])
            plt.subplot(235), plt.imshow(bgr_to_rgb(np.real(f1))), \
                plt.title('fft(image(encoded))')
            plt.xticks([]), plt.yticks([])

        rwm = (f2 - f1) / alpha
        rwm = np.real(rwm)
        print("rwm after calculation: ", rwm)

        if debug:
            plt.subplot(233), plt.imshow(bgr_to_rgb(rwm)), \
                plt.title('encrypted(watermark)')
            plt.xticks([]), plt.yticks([])

        wm = np.zeros_like(rwm)
        for i in range(int(rwm.shape[0] * 0.5)):
            for j in range(rwm.shape[1]):
                wm[m[i]][n[j]] = np.uint8(rwm[i][j])
        for i in range(int(rwm.shape[0] * 0.5)):
            for j in range(rwm.shape[1]):
                wm[rwm.shape[0] - i - 1][rwm.shape[1] - j - 1] = wm[i][j]

        if not cv2.imwrite(fn3, wm):
            print(f"Error saving file {fn3}")

        if debug:
            plt.subplot(236), plt.imshow(bgr_to_rgb(wm)), plt.title('watermark')
            plt.xticks([]), plt.yticks([])

        if debug:
            plt.show()


if __name__ == '__main__':
    print("Current working directory:", os.getcwd())
    main()

11.txt有442768个字符,做个字频统计,再取前16个字符

https://github.com/JasonJHu/FrequencyCount

下载字频统计程序

先行编译

​ 1.python package.py

​ 2.bin\build目录就会出现exe程序

如下图报错:是没安装pyinstaller

pip install pyinstaller

安装后编译成功

etaonrhisdluygwmfc. ,bp"k'Hv-ITS?ADMRWPGN!FxBOYjCEzqLQUV;K:J)(134Z0792X5*~86\

前16位字符:etaonrhisdluygw (去掉第一位无效字符其实就15位),对照编码字典decode.txt进行编码,写个脚本自动替换,还是使用python和qt混合编程做个有窗口的app,源代码如下:

import sys
import os
import unicodedata
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QTextEdit, QFileDialog


class TextReplaceTool(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.dict_path = None

    def init_ui(self):
        # 整体布局
        main_layout = QVBoxLayout()

        # 选择字典区域布局
        dict_layout = QHBoxLayout()
        self.select_dict_button = QPushButton('选择替换字典')
        self.select_dict_button.clicked.connect(self.select_dict)
        dict_layout.addWidget(self.select_dict_button)
        main_layout.addLayout(dict_layout)

        # 替换按钮
        self.replace_button = QPushButton('替换内容')
        self.replace_button.clicked.connect(self.replace_text)
        main_layout.addWidget(self.replace_button)

        # 文本编辑区域
        self.text_edit = QTextEdit()
        main_layout.addWidget(self.text_edit)

        self.setLayout(main_layout)
        self.setWindowTitle('文本查找替换工具')
        self.show()

    def select_dict(self):
        self.dict_path, _ = QFileDialog.getOpenFileName(self, "选择字典文件", "", "Text Files (*.txt)")

    def read_dict_file(self):
        replace_dict = {}
        if not self.dict_path:
            return replace_dict
        try:
            with open(self.dict_path, 'r', encoding='UTF - 8') as f:
                lines = f.readlines()
                keys_seen = set()
                for line in lines:
                    parts = line.strip().split('=', 1)
                    if len(parts)!= 2:
                        continue
                    key = parts[0].strip()
                    value = parts[1].strip()
                    # 处理转义字符,这里仅以换行符为例
                    value = value.replace('\\n', '\n')
                    if not key:
                        continue
                    if not value:
                        continue
                    if key in keys_seen:
                        continue
                    keys_seen.add(key)
                    replace_dict[key] = value
        except FileNotFoundError:
            pass
        return replace_dict

    def replace_text(self):
        replace_dict = self.read_dict_file()
        if not replace_dict:
            return
        text = self.text_edit.toPlainText()
        new_text = ""
        i = 0
        while i < len(text):
            char = text[i]
            # 将字符转换为半角形式(如果是全角英文字母)
            char = unicodedata.normalize('NFKC', char)
            if char in replace_dict:
                print(f"字符 {char} 在位置 {i} 将被替换为 {replace_dict[char]}")
                new_text += replace_dict[char]
            else:
                new_text += char
            i += 1
        # 尝试编码转换,这里假设为UTF - 8编码
        try:
            new_text = new_text.encode('utf - 8').decode('utf - 8')
        except UnicodeDecodeError:
            pass
        self.text_edit.setPlainText(new_text)
        self.text_edit.repaint()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TextReplaceTool()
    sys.exit(app.exec_())

运行界面:

把文本框的结果复制出来

QW8obWdIWT9pMkF-sd5REtRQSQW jVfXiE/WSFTajBtcw= (44 个字符)

去掉-sd5RE 和tRQSQW每三位倒序 SQWtRQ  ,最后加=,是wp官方结果,不知逻辑从哪来???

QW8obWdIWT9pMkFSQWtRQjVfXiE/WSFTajBtcw==               (36 个字符)

python basecrack.py --magic

 flag{have_a_good_day1}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值