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}



浙公网安备 33010602011771号