MilkTeA

GeekCTF MISC方向WP

签个到吧

首先我们要知道nc是什么
NC 全名 Netcat,作者是 Hobbit && ChrisWysopal。因其功能十分强大,体积小巧而出名,又被大家称为“瑞士军刀”
并且nc是linux自带,所以我们需要在linux系统中使用nc连接服务器

知道是猜数字的游戏,猜数字游戏使用二分法是最快的解决方法,即每次取区间中间值即可以最少次数解出

flag{Th1s_ls_y0u4_r3w@rd}

八卦

看附件有很多卦象图,都是根据01编写的,让AI写一个提取脚本还原二进制数据

点击查看代码
import os
import re
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np


def extract_binary_from_png(png_path):
    """从PNG文件中提取二进制字符串和编号信息"""
    try:
        with open(png_path, 'rb') as f:
            png_data = f.read()

        # 方法1:从文件名中提取二进制字符串和编号
        filename = os.path.basename(png_path)
        binary_match = re.search(r'_([01]{3})\.png', filename)
        seq_match = re.search(r'trigram_(\d{3})_', filename)

        binary_str = binary_match.group(1) if binary_match else None
        seq_num = int(seq_match.group(1)) if seq_match else None

        if binary_str and seq_num:
            return binary_str, seq_num

        # 方法2:从文件末尾查找编号信息(如果方法1失败)
        marker = b'png_number:'
        marker_pos = png_data.rfind(marker)
        if marker_pos != -1:
            # 提取从标记开始到IEND块结束的数据
            extra_data = png_data[marker_pos + len(marker):]
            # 尝试找到数字部分
            seq_num_str = b''
            for b in extra_data:
                if 48 <= b <= 57:  # 数字0-9的ASCII码
                    seq_num_str += bytes([b])
                else:
                    break
            if seq_num_str:
                seq_num = int(seq_num_str.decode('ascii'))

        # 如果二进制字符串仍未获取,尝试从图像内容识别
        if not binary_str:
            binary_str = recognize_binary_from_image(png_path)

        return binary_str, seq_num

    except Exception as e:
        print(f"处理文件 {png_path} 时出错: {str(e)}")
        return None, None


def recognize_binary_from_image(png_path):
    """从图像内容识别二进制字符串"""
    try:
        img = Image.open(png_path)
        img_array = np.array(img)

        # 简单的图像识别逻辑
        # 假设图像中有3条水平线,从上到下代表二进制位
        height, width = img_array.shape[:2]
        step = height // 4  # 每条线的大致位置

        binary_str = ''
        for i in range(3):
            y_pos = height - (i + 1) * step
            # 检查中间部分是否有连续黑线(阳爻)
            middle_section = img_array[y_pos, width // 4:3 * width // 4]
            if np.mean(middle_section) < 128:  # 暗色代表阳爻
                binary_str += '1'
            else:
                binary_str += '0'

        return binary_str
    except:
        return None


def restore_binary_string(png_dir):
    """从PNG目录中恢复原始二进制字符串"""
    png_files = [f for f in os.listdir(png_dir) if f.endswith('.png')]
    if not png_files:
        print("错误: 指定的目录中没有PNG文件")
        return None

    # 提取所有文件的信息
    data = []
    for png_file in png_files:
        binary_str, seq_num = extract_binary_from_png(os.path.join(png_dir, png_file))
        if binary_str is not None and seq_num is not None:
            data.append((seq_num, binary_str))
        else:
            print(f"警告: 无法从文件 {png_file} 中提取完整信息")

    if not data:
        print("错误: 未能从任何文件中提取有效信息")
        return None

    # 按编号排序
    data.sort(key=lambda x: x[0])

    # 组合二进制字符串
    restored_str = ''.join([binary for _, binary in data])
    return restored_str


def verify_restoration(original_file, restored_str):
    """验证还原结果是否正确"""
    try:
        with open(original_file, 'r') as f:
            original_str = f.read().strip()

        # 移除可能补的0
        min_len = min(len(original_str), len(restored_str))
        original_str = original_str[:min_len]
        restored_str = restored_str[:min_len]

        if original_str == restored_str:
            print("验证成功: 还原的二进制字符串与原始文件一致")
            return True
        else:
            print("验证失败: 还原的二进制字符串与原始文件不一致")
            print(f"原始字符串 (前100字符): {original_str[:100]}")
            print(f"还原字符串 (前100字符): {restored_str[:100]}")
            return False
    except:
        print("无法验证结果,原始文件可能不存在")
        return False


if __name__ == "__main__":
    # 配置参数
    png_directory = "numbered_png"  # PNG文件目录
    original_file = "1.txt"  # 原始二进制文件

    print("开始从PNG文件中还原二进制字符串...")
    restored_binary = restore_binary_string(png_directory)

    if restored_binary:
        print("\n还原的二进制字符串 (前200字符):")
        print(restored_binary[:200])
        print(f"\n总长度: {len(restored_binary)} 位")

        # 验证还原结果
        if os.path.exists(original_file):
            verify_restoration(original_file, restored_binary)
        else:
            print("未找到原始文件,跳过验证")

        # 保存还原结果
        output_file = "restored_binary.txt"
        with open(output_file, 'w') as f:
            f.write(restored_binary)
        print(f"\n还原结果已保存到: {output_file}")
    else:
        print("未能成功还原二进制字符串")

将提取的二进制数据转换为十六进制再转换为字符串

五行平衡

出题思路:一开始其实想着出阴阳五行,在打XYCTF的时候查资料看到了矩阵于是对这题有了想法

WP:我们先看规则,金木水火土五大元素,选手选择一个元素则会以该元素自身为首尾,以相生和相克的方式构建四方阵(矩阵),根据这个矩阵制作令牌,我们只需还原相生和相克的矩阵编码即可。

例,当我们输入1时,我们选择"金"元素
那么关于"金"元素的相生矩阵则为[[1,3] (金生水),[5,1] (土生金))
相克矩阵则为[[1,2] (金克木),4,1]

而相生和相克的矩阵相乘与选择元素数字后的矩阵相同,为[[13,5],[9,11]]

因此我们提取原始矩阵数字进行base64加密后提交即可得到flag{Th!s_i$_R3c0gn1ti@n_To4en}

posted @ 2025-04-13 21:56  MilK_TeA  阅读(58)  评论(0)    收藏  举报