[GHCTF 2025]Mio?Ryo?Soyo?

PyInstaller 打包,使用 pyinstxtractor-ng 解包

反编译

使用 uncompyle6 将 pyc 转成 py 源文件

uncompyle6 program.pyc > program.py

# uncompyle6 version 3.9.2 # Python bytecode version base 3.8.0 (3413) # Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] # Embedded file name: program.py from Secret import * if __name__ == "__main__": print("输入:", end="") aaaaaaaaaaaaa = input() wwwwwwwwwww = l(aaaaaaaaaaaaa) if sssssssssssss == wwwwwwwwwww.encode(): print("哦,对的。") else: print("哎,并非。") input() # okay decompiling program.pyc

发现导入了自定义包 Secret

在PYZ-00.pyz_extracted 文件夹下找到 Secret.pyc

同样的反编译uncompyle6 Secret.pyc > Secret.py

# uncompyle6 version 3.9.2 # Python bytecode version base 3.8.0 (3413) # Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] # Embedded file name: Secret.py from SecretEncrypt import * sssssssssssss = bytes([57, 118, 33, 114, 68, 56, 117, 115, 34, 52, 52, 95, 78, 40, 49, 59, 95, 85, 63, 122, 54, 33, 77, 110, 49, 54, 34, 109, 106, 122, 60, 92, 108, 91, 61, 51, 42, 62, 35, 38, 52, 67, 62, 122, 116, 48, 76, 50, 67, 51, 59, 41, 122, 45, 45, 51, 90]) def l(_: str): return SSSooooyyooo(MMMMiiiiiio.MMMMiiooooooo(SSSooooyyooo(RRRRyyooo.RRRRRRRyyyyooooo(_.encode()), 7).encode()), 9) # okay decompiling Secret.pyc

导入了自定义包SecretEncrypt

同样uncompyle6 SecretEncrypt.pyc > SecretEncrypt.py

# uncompyle6 version 3.9.2 # Python bytecode version base 3.8.0 (3413) # Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] # Embedded file name: SecretEncrypt.py import math class MMMMiiiiiio: MMiiiiiiooo = "".join([chr(Miiooooooooo) for Miiooooooooo in range(33, 118)]) @staticmethod def MMMMiiooooooo(MMMMMMMMMiiiooo: bytes) -> str: MMMMiiiiioooooooooo = "" MMMMMMMiiiiioo = (4 - len(MMMMMMMMMiiiooo) % 4) % 4 MMMMMMMMMiiiooo += b'\x00' * MMMMMMMiiiiioo for MMMMMMiiiiiio in range(0, len(MMMMMMMMMiiiooo), 4): MMMMiiiiiiooooo = MMMMMMMMMiiiooo[MMMMMMiiiiiio[:MMMMMMiiiiiio + 4]] MMMMMMiiioooooo = int.from_bytes(MMMMiiiiiiooooo, "big") MMMMMMMiiooooooooo = "" for _ in range(5): MMMMMMMiiooooooooo = MMMMiiiiiio.MMiiiiiiooo[MMMMMMiiioooooo % 85] + MMMMMMMiiooooooooo MMMMMMiiioooooo //= 85 else: MMMMiiiiioooooooooo += MMMMMMMiiooooooooo else: if MMMMMMMiiiiioo: MMMMiiiiioooooooooo = MMMMiiiiioooooooooo[None[:-MMMMMMMiiiiioo]] return MMMMiiiiioooooooooo class RRRRyyooo: RRRRyooooooo = "".join([chr(RRRRRRRyyyyyoooo) for RRRRRRRyyyyyoooo in range(48, 93)]) @staticmethod def RRRRRRRyyyyooooo(RRRRRRyyyoooooo: bytes) -> str: RRRRyyyyyooo = [] RRyyyyyyyyyoooooo = 0 while RRyyyyyyyyyoooooo < len(RRRRRRyyyoooooo): if RRyyyyyyyyyoooooo + 1 < len(RRRRRRyyyoooooo): RRRRRRRRRyyo = RRRRRRyyyoooooo[RRyyyyyyyyyoooooo] << 8 | RRRRRRyyyoooooo[RRyyyyyyyyyoooooo + 1] RRRRyyyyyooo.append(RRRRyyooo.RRRRyooooooo[RRRRRRRRRyyo % 45]) RRRRRRRRRyyo //= 45 RRRRyyyyyooo.append(RRRRyyooo.RRRRyooooooo[RRRRRRRRRyyo % 45]) RRRRRRRRRyyo //= 45 RRRRyyyyyooo.append(RRRRyyooo.RRRRyooooooo[RRRRRRRRRyyo]) RRyyyyyyyyyoooooo += 2 else: RRRRRRRRRyyo = RRRRRRyyyoooooo[RRyyyyyyyyyoooooo] RRRRyyyyyooo.append(RRRRyyooo.RRRRyooooooo[RRRRRRRRRyyo % 45]) RRRRRRRRRyyo //= 45 RRRRyyyyyooo.append(RRRRyyooo.RRRRyooooooo[RRRRRRRRRyyo]) RRyyyyyyyyyoooooo += 1 return "".join(RRRRyyyyyooo) def SSSooooyyooo(SSSSooyoooooo, SSSSSoyyooooo): SSoooooyyyyyyoo = [] for SSSSSSSSSoyooo in SSSSooyoooooo: if "a" <= SSSSSSSSSoyooo <= "z": SSSSoooyooooooo = (ord(SSSSSSSSSoyooo) - ord("a") + SSSSSoyyooooo) % 26 SSoooooyyyyyyoo.append(chr(ord("a") + SSSSoooyooooooo)) elif "0" <= SSSSSSSSSoyooo <= "9": SSSSoooyooooooo = (ord(SSSSSSSSSoyooo) - ord("0") - SSSSSoyyooooo) % 10 SSoooooyyyyyyoo.append(chr(ord("0") + SSSSoooyooooooo)) else: SSoooooyyyyyyoo.append(SSSSSSSSSoyooo) else: return "".join(SSoooooyyyyyyoo) # okay decompiling SecretEncrypt.pyc

优化变量名

# uncompyle6 version 3.9.2 # Python bytecode version base 3.8.0 (3413) # Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] # Embedded file name: program.py from Secret import * if __name__ == "__main__": print("输入:", end="") user_input = input() encrypted_input = encrypt_flow(user_input) if TARGET_HASH == encrypted_input.encode(): print("哦,对的。") else: print("哎,并非。") input() # okay decompiling program.pyc
# uncompyle6 version 3.9.2 # Python bytecode version base 3.8.0 (3413) # Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] # Embedded file name: Secret.py from SecretEncrypt import * TARGET_HASH = bytes([57, 118, 33, 114, 68, 56, 117, 115, 34, 52, 52, 95, 78, 40, 49, 59, 95, 85, 63, 122, 54, 33, 77, 110, 49, 54, 34, 109, 106, 122, 60, 92, 108, 91, 61, 51, 42, 62, 35, 38, 52, 67, 62, 122, 116, 48, 76, 50, 67, 51, 59, 41, 122, 45, 45, 51, 90]) def encrypt_flow(plain_text: str): return caesar_cipher(Base85Encoder.encode(caesar_cipher(Base45Encoder.encode(plain_text.encode()), 7).encode()), 9) # okay decompiling Secret.pyc
# uncompyle6 version 3.9.2 # Python bytecode version base 3.8.0 (3413) # Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] # Embedded file name: SecretEncrypt.py import math class Base85Encoder: CHARSET = "".join([chr(i) for i in range(33, 118)]) @staticmethod def encode(data: bytes) -> str: result = "" padding_size = (4 - len(data) % 4) % 4 data += b'\x00' * padding_size for i in range(0, len(data), 4): chunk = data[i[:i + 4]] val = int.from_bytes(chunk, "big") chunk_res = "" for _ in range(5): chunk_res = Base85Encoder.CHARSET[val % 85] + chunk_res val //= 85 else: result += chunk_res else: if padding_size: result = result[None[:-padding_size]] return result class Base45Encoder: CHARSET = "".join([chr(i) for i in range(48, 93)]) @staticmethod def encode(data: bytes) -> str: res = [] i = 0 while i < len(data): if i + 1 < len(data): val = data[i] << 8 | data[i + 1] res.append(Base45Encoder.CHARSET[val % 45]) val //= 45 res.append(Base45Encoder.CHARSET[val % 45]) val //= 45 res.append(Base45Encoder.CHARSET[val]) i += 2 else: val = data[i] res.append(Base45Encoder.CHARSET[val % 45]) val //= 45 res.append(Base45Encoder.CHARSET[val]) i += 1 return "".join(res) def caesar_cipher(text, shift): res = [] for char in text: if "a" <= char <= "z": new_val = (ord(char) - ord("a") + shift) % 26 res.append(chr(ord("a") + new_val)) elif "0" <= char <= "9": new_val = (ord(char) - ord("0") - shift) % 10 res.append(chr(ord("0") + new_val)) else: res.append(char) else: return "".join(res) # okay decompiling SecretEncrypt.pyc

通过caesar_cipher(Base85Encoder.encode(caesar_cipher(Base45Encoder.encode(plain_text.encode()), 7).encode()), 9)可以得知加密顺序为:

  • Base45 加密 码表0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\
  • 凯撒密码 偏移 7
  • Base85 加密 码表!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu
  • 凯撒密码 偏移 9

最后与TARGET_HASH对比验证

代码中的凯撒密码为魔改版,Base45 为非标准码表,Base85 为标准Adobe Ascii85(还有另一种常见的是IPv6 / RFC 1924)

EXP

将加密函数修改成解密函数

import base64 def caesar_cipher(text, shift): res = [] for char in text: if "a" <= char <= "z": new_val = (ord(char) - ord("a") + shift) % 26 res.append(chr(ord("a") + new_val)) elif "0" <= char <= "9": new_val = (ord(char) - ord("0") - shift) % 10 res.append(chr(ord("0") + new_val)) else: res.append(char) else: return "".join(res) def Base45decoder(data): CHARSET = "".join([chr(i) for i in range(48, 93)]) result = "" for i in range(0, len(data), 3): a = CHARSET.index(data[i]) b = CHARSET.index(data[i+1]) c = CHARSET.index(data[i+2]) n = a + (b * 45) + (c * 45 * 45) result += chr(n >> 8) result += chr(n & 0xFF) return result enc = [57, 118, 33, 114, 68, 56, 117, 115, 34, 52, 52, 95, 78, 40, 49, 59, 95, 85, 63, 122, 54, 33, 77, 110, 49, 54, 34, 109, 106, 122, 60, 92, 108, 91, 61, 51, 42, 62, 35, 38, 52, 67, 62, 122, 116, 48, 76, 50, 67, 51, 59, 41, 122, 45, 45, 51, 90] # sourc enc = "".join([chr(i) for i in enc]) print(enc) # caesar enc = caesar_cipher(enc, -9) print(enc) # base85 enc = base64.a85decode(enc).decode() print(enc) # caesar enc = caesar_cipher(enc, -7) print(enc) # base45 enc = Base45decoder(enc) print(enc)
9v!rD8us"44_N(1;_U?z6!Mn16"mjz<\l[=3*>#&4C>zt0L2C3;)z--3Z 8m!iD7lj"33_N(0;_U?q5!Me05"daq<\c[=2*>#&3C>qk9L1C2;)q--2Z JX2NG:CM:KJ?S0=:>?NC>K5<V29Z5<Y:9C=;LA1RQ9G:7 JX9NG:CM:KJ?S7=:>?NC>K2<V96Z2<Y:6C=;LA8RQ6G:4 NSSCTF{Th3y'r3_a11_p1aY_Ba5e!}

NSSCTF{Th3y'r3_a11_p1aY_Ba5e!}

总结

本题考验对算法的熟悉程度,涉及 base45、base85、Caesar 算法,并且需要解包反编译 pyc、反编译自定义 python 库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1180330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

让老手机变智能!Open-AutoGLM低配设备适配经验

让老手机变智能&#xff01;Open-AutoGLM低配设备适配经验 1. 引言 1.1 老旧设备的智能化困境 随着AI技术向终端侧迁移&#xff0c;越来越多用户希望在现有设备上体验智能代理服务。然而&#xff0c;当前多数AI Agent框架依赖高性能GPU和最新芯片架构&#xff0c;导致大量运…

从0开始学图像识别,阿里开源中文模型超详细教程

从0开始学图像识别&#xff0c;阿里开源中文模型超详细教程 1. 引言&#xff1a;为什么需要中文通用图像识别&#xff1f; 在当前AI大模型快速发展的背景下&#xff0c;图像识别技术已广泛应用于电商、医疗、安防、内容审核等多个领域。然而&#xff0c;大多数开源视觉模型以…

NotaGen:高质量符号化音乐生成,WebUI轻松上手

NotaGen&#xff1a;高质量符号化音乐生成&#xff0c;WebUI轻松上手 在一次数字艺术创作工作坊中&#xff0c;一位作曲系研究生尝试为原创交响诗配乐&#xff0c;却因灵感枯竭陷入瓶颈。他打开本地部署的 NotaGen WebUI&#xff0c;选择“浪漫主义”时期、“柴可夫斯基”风格…

内存溢出怎么办?低配设备运行优化建议

内存溢出怎么办&#xff1f;低配设备运行优化建议 1. 引言&#xff1a;低配环境下的推理挑战与应对策略 在实际部署深度学习模型时&#xff0c;尤其是像「万物识别-中文-通用领域」这类基于大规模预训练的视觉模型&#xff0c;开发者常常面临一个现实问题&#xff1a;硬件资源…

FSMN VAD社区贡献指南:提交PR和issue的正确姿势

FSMN VAD社区贡献指南&#xff1a;提交PR和issue的正确姿势 1. 贡献背景与价值 1.1 开源项目的重要性 FSMN VAD 是基于阿里达摩院 FunASR 框架开发的语音活动检测&#xff08;Voice Activity Detection, VAD&#xff09;模型&#xff0c;具备高精度、低延迟和轻量级等优势。…

Emotion2Vec+ Large前端界面解析:Gradio组件布局与交互逻辑

Emotion2Vec Large前端界面解析&#xff1a;Gradio组件布局与交互逻辑 1. 引言 1.1 项目背景与开发动机 在语音情感识别技术快速发展的背景下&#xff0c;Emotion2Vec Large作为阿里达摩院推出的大规模预训练模型&#xff0c;凭借其在42526小时多语种数据上的深度训练&#…

轻量级视觉语言模型:Qwen3-VL-8B优势

轻量级视觉语言模型&#xff1a;Qwen3-VL-8B优势 1. 引言 随着多模态人工智能的快速发展&#xff0c;视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;在图像理解、图文生成、跨模态检索等场景中展现出巨大潜力。然而&#xff0c;大多数高性能模型依赖庞大…

实测YOLOv13性能:小目标检测精度提升太明显

实测YOLOv13性能&#xff1a;小目标检测精度提升太明显 在工业质检、无人机巡检和智能安防等场景中&#xff0c;小目标检测一直是极具挑战性的任务。传统目标检测模型往往因感受野限制或特征融合不足&#xff0c;难以准确识别远距离的微小物体。就在近期&#xff0c;Ultralyti…

多模型对比评测:cv_unet与RemBG抠图效果与性能全面PK

多模型对比评测&#xff1a;cv_unet与RemBG抠图效果与性能全面PK 1. 引言 1.1 技术选型背景 图像抠图&#xff08;Image Matting&#xff09;是计算机视觉中的关键任务之一&#xff0c;广泛应用于人像处理、电商展示、广告设计和视频编辑等领域。随着深度学习的发展&#xf…

opencode build Agent使用:自动化编译流程实战

opencode build Agent使用&#xff1a;自动化编译流程实战 1. 引言 在现代软件开发中&#xff0c;构建和编译流程的自动化已成为提升研发效率的关键环节。传统的CI/CD工具虽然功能强大&#xff0c;但往往需要复杂的配置与外部服务依赖&#xff0c;难以满足本地快速迭代的需求…

AI读脸术快速验证:上传自拍即刻获取性别年龄预测

AI读脸术快速验证&#xff1a;上传自拍即刻获取性别年龄预测 1. 技术背景与核心价值 在计算机视觉领域&#xff0c;人脸属性分析是一项极具实用价值的技术方向。从智能安防到个性化推荐&#xff0c;从用户画像构建到交互式娱乐应用&#xff0c;对人脸的性别与年龄段进行快速、…

FRCRN语音降噪部署:多卡并行推理配置指南

FRCRN语音降噪部署&#xff1a;多卡并行推理配置指南 1. 技术背景与应用场景 随着智能语音设备在真实环境中的广泛应用&#xff0c;语音信号常受到背景噪声的严重干扰&#xff0c;影响识别准确率和用户体验。FRCRN&#xff08;Full-Resolution Complex Residual Network&…

Qwen3-0.6B对话管理:状态跟踪与策略决策模块设计

Qwen3-0.6B对话管理&#xff1a;状态跟踪与策略决策模块设计 1. 技术背景与问题提出 随着大语言模型在对话系统中的广泛应用&#xff0c;如何构建具备上下文理解、意图识别和长期记忆能力的智能代理&#xff08;Agent&#xff09;成为工程实践中的关键挑战。传统的问答系统往…

AI智能文档扫描仪入门必看:无需模型权重的纯算法扫描方案

AI智能文档扫描仪入门必看&#xff1a;无需模型权重的纯算法扫描方案 1. 引言 在日常办公与学习中&#xff0c;纸质文档的数字化需求日益增长。传统扫描仪体积大、成本高&#xff0c;而手机拍照虽便捷却存在角度倾斜、阴影干扰、背景杂乱等问题。为此&#xff0c;“AI 智能文…

从图片到文字:Qwen3-VL-8B保姆级使用教程

从图片到文字&#xff1a;Qwen3-VL-8B保姆级使用教程 1. 引言&#xff1a;为什么需要轻量级多模态模型&#xff1f; 在当前AI应用向边缘设备迁移的大趋势下&#xff0c;如何在资源受限的终端设备上运行高性能多模态模型&#xff0c;成为开发者面临的核心挑战。传统大参数量的…

边缘设备部署YOLOv9,Jetson上跑得流畅吗?

边缘设备部署YOLOv9&#xff0c;Jetson上跑得流畅吗&#xff1f; 1. 背景与挑战&#xff1a;边缘端目标检测的现实需求 在智能安防、工业质检和移动机器人等应用场景中&#xff0c;实时目标检测是核心能力之一。然而&#xff0c;将高性能模型部署到资源受限的边缘设备&#x…

轻量应用:Qwen2.5-0.5B指南

轻量应用&#xff1a;Qwen2.5-0.5B指南 1. 引言 随着大模型技术的快速发展&#xff0c;如何在资源受限的设备上实现高效、流畅的AI对话体验成为边缘计算和轻量化部署的重要课题。传统的大型语言模型虽然性能强大&#xff0c;但对硬件要求高&#xff0c;难以在无GPU支持的环境…

IndexTTS-2-LLM性能优化:让语音合成速度提升2倍

IndexTTS-2-LLM性能优化&#xff1a;让语音合成速度提升2倍 1. 背景与挑战&#xff1a;传统TTS在本地部署中的瓶颈 随着大语言模型&#xff08;LLM&#xff09;技术的快速发展&#xff0c;语音合成系统正从“机械朗读”向“情感化表达”演进。IndexTTS-2-LLM 作为一款融合LLM…

工业网关连接中的USB Serial Port驱动下载详解

工业网关调试避坑指南&#xff1a;USB转串口驱动选型与实战排错全解析 在工业自动化现场&#xff0c;你是否经历过这样的场景&#xff1f; 手握新到的工业网关&#xff0c;准备通过串口连接PLC读取数据。线缆插上&#xff0c;电脑却“无动于衷”——设备管理器里显示一个黄色…

Kotaemon电商客服整合:商品说明书自动应答机器人

Kotaemon电商客服整合&#xff1a;商品说明书自动应答机器人 1. 技术背景与应用场景 随着电商平台的快速发展&#xff0c;用户对客服响应速度和准确性的要求日益提高。传统人工客服面临成本高、响应慢、知识覆盖有限等问题&#xff0c;而通用聊天机器人又难以精准理解复杂的产…