加密数据还原
SkillCommerce & finance加密数据还原:定位解密函数、写解密脚本。 触发词:解密、decrypt、还原数据、解密流量
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the 加密数据还原 skill
What this skill tells your AI
The instructions your AI receives, as published by dslsdzc/rev-skills in .claude/skills/re-crypto-decrypt/SKILL.md and read by ahel’s review.
何时使用 / 何时不用
- 用:需要把密文(数据 blob / 流量 / 配置段)还原成明文
- 用:算法与密钥已知(或已由 [[re-crypto-id]] / [[re-crypto-keys]] 得出),需要批量解密
- 用:从样本里还原解密逻辑并重写为独立可复用的脚本
- 不用:算法/密钥都未知(先 [[re-crypto-id]] → [[re-crypto-keys]])
- 不用:静态可读的明文([[re-triage]] 熵低直接读)
- 不用:想跑原样本看输出(那是 [[re-behavior]] / [[re-sandbox]] 的活——解密脚本是为了脱离样本复现)
工具准备
所有工具先验证再使用。本技能处理的是转储/反编译产物与密文数据,运行样本环节在 [[re-sandbox]] 内([[re-analyze/platform-tips]] 最高原则)。
python3 + pycryptodome —— 解密脚本主力
- Linux:
apt install python3 python3-pip/dnf install python3 python3-pip/pacman -S python python-pip - macOS:
brew install python - Windows: python.org 安装包(勾选 Add to PATH);WSL 内 Linux 版
- 加密库:
pip install pycryptodome(AES/DES/RSA/ChaCha 等标准算法) - 验证:
python3 -c "from Crypto.Cipher import AES; print('ok')";python3 --version
目标程序转储/反编译产物 —— 还原算法的依据
- 转储: [[re-memdump]] 默认转储(gcore)——定位密文输入点与解密调用现场
- 反编译: [[re-ghidra]] / [[re-ida]] / [[re-radare2]] 的产物(函数反编译视图)
- 验证:
file out是 ELF core;反编译器里能找到目标函数(ghidra/rizin可启动)
angr(可选)—— 符号执行补足难还原的逻辑
- 全平台:
pip install angr(Python 3.8+,依赖多,建议 venv:python3 -m venv venv && venv/bin/pip install angr) - 验证:
venv/bin/python -c "import angr; print(angr.__version__)" - 用途: 反编译分支爆炸/混淆严重时,用符号执行求解密函数输出(加载目标二进制 → 设密文输入为符号 → 约束求解)
操作步骤
按顺序执行,每步记下结果。前提:算法([[re-crypto-id]])与密钥([[re-crypto-keys]])已确认或至少有一方候选;脚本与验证结果(明文样本 + sha256)存档供报告引用。
-
证伪"密文":先定位真实密文边界(跳过此步是加密分析最常见的失败方式):
- 高熵段可能是"伪密文"——容器/压缩数据流被误当加密层(如 zip 数据本体、附加在图片后的压缩流)。压缩数据熵同样是 8.0,与加密不可区分
- 先做整体结构观察:文件头/尾魔数、格式 marker 分布(JPEG 逐段统计大小)、尾部已知结构当锚点(zip EOCD 的
cd_offset/cd_size反推数据起点,EOCD 签名是已知明文) - 找格式结束标记用第一个(JPEG EOI
FFD9、PNG IEND),不是最后一个——数据流里碰巧出现的标记字节对会把分析带偏(曾把 zip 数据中的FFD9误当图片结尾,把数据流当密文穷举) - 同尺寸文件先比尾部 16 字节/整体哈希——"换头副本"(同一 payload 的第二种封装,仅头部不同)直接省掉一整条支线
- 压缩率是信号:解压后明显变大的层说明内容有结构(可压=编码/明文),接近 1:1 说明内层已压缩或加密
- 确认是孤立高熵 blob 后再进入步骤 1 的密文定位
-
定位解密函数(交叉引用密文输入点):
- 从密文偏移出发:[[re-crypto-id]] 步骤 2 的高熵区偏移 → 反编译器里找读取该偏移/该全局变量的函数 → 沿调用链看谁写入了它(写入方常是解密函数)
- 从 API 出发:[[re-crypto-keys]] 步骤 4 找到的
Crypt*/EVP_*调用点就是候选;观察入参的密文指针是否指向步骤 2 的偏移 - 动态辅助: [[re-gdb]] / [[re-x64dbg]] 在候选函数下断点(沙箱内),打印入参/返回值,确认它输出可读明文
- 找不到明确函数 → 密文可能由内联展开的算法处理(无调用边界),回 [[re-crypto-id]] 用数据特征定位(常量表引用处)
-
反编译还原算法:
- 把反编译视图逐段抄译成伪代码,明确:算法(AES-CBC/自定义 XOR…)、密钥与 IV 来源(固定值/派生/上下文)、模式与填充(CBC 的 IV 在哪、PKCS7 还是零填充)
- 自定义算法: 逐条翻译位运算(XOR/移位/查表),注意字节序([[re-proto-rev]] 坑 1 同理——长度/密钥字段先试大小端)
- 还原标准算法时留意细节:AES 用 CBC 还是 ECB、key 长度 16/24/32、IV 是否复用密钥(常见错误实现,见坑 1)
- 反编译看不清的循环/查表逻辑 → angr 符号执行兜底(构造求解脚本,把函数当黑盒求输出)
-
重写为独立脚本(python):
# decrypt.py —— 按反编译还原的算法重写 from Crypto.Cipher import AES import sys key = bytes.fromhex("...") # 来自 [[re-crypto-keys]] 步骤 1/2/5 iv = key[:16] # 样本实现: IV = key 前 16 字节 data = open(sys.argv[1], 'rb').read() pt = AES.new(key, AES.MODE_CBC, iv).decrypt(data) print(pt) # 或写文件 + 后续校验- 脚本参数化(密钥/IV/输入文件走参数或配置),一次写对、反复复用——批量解流量用
- 关键:脚本逻辑必须与样本一致(填充处理、尾部截断),不一致时回查边界条件(见坑 1)
-
用已知明文验证:
- 已知明文来源:协议头 magic(如
\xAA\x55)、文件头(PKzip /\x89PNG)、报文字段([[re-proto-rev]] 步骤 2 的固定头)、或 [[re-behavior]] 行为里观察到的明文串 - 验证方式:解密输出里能找到已知明文片段 → 成功;找不到 → 依次检查:密钥/IV 是否对([[re-crypto-keys]] 候选逐个试)、字节序、填充处理、是否还有外层加密(见坑 3)
- 无已知明文时用"可读性"验证:输出可打印率 >70% 或通过
file -识别出格式(PDF/zip/文本)→ 视为成功候选
- 已知明文来源:协议头 magic(如
-
流量场景:解出明文流量流:
- 已按 [[re-crypto-id]] / [[re-crypto-keys]] 确认流量加密算法与密钥后,从 pcap 提取密文载荷([[re-netcap]] 步骤 3 tshark 导出):
tshark -r c2.pcap -Y 'tcp.payload' -T fields -e data.data | sed 's/://g' | xxd -r -p > payloads.bin - 写批量脚本:按流切分(每 TCP 流一段)、逐段调用解密逻辑(同步骤 3 的脚本),输出明文流文件
- 验证: 明文流里能看到协议结构(会话序号/命令字),再转 [[re-proto-rev]] 做状态机重建
- 注意会话密钥变化(每次握手重新派生)→ 脚本里为每个会话取对应密钥([[re-crypto-keys]] 步骤 5 的派生还原)
- 已按 [[re-crypto-id]] / [[re-crypto-keys]] 确认流量加密算法与密钥后,从 pcap 提取密文载荷([[re-netcap]] 步骤 3 tshark 导出):
跨域联合
- [[re-protocol]]:本网关工作流第 4 步(解密)——加密通信链路的落地点(crypto-id → crypto-keys → crypto-decrypt → proto-rev)
- [[re-malware]]:C2 流量解密——re-malware 第 4 步;解出的明文(指令/配置)进行为判断与 IOC([[re-ioc]])
- [[re-firmware]]:固件加密层/加密通信解密——配合 [[re-fw-extract]] 解包失败时的加密层处理
- [[re-crypto-id]] / [[re-crypto-keys]]:上游——算法与密钥的输入来源
- [[re-memdump]]:密文输入点定位与解密调用现场(转储产物)
- [[re-anti-analysis]]:解密在壳内时先脱壳(见坑 2);[[re-gdb]] / [[re-x64dbg]] 动态辅助确认函数行为
- 解出的明文转 [[re-proto-rev]] 重建状态机,或按 [[re-firmware]] / [[re-malware]] 流程继续
常见坑与陷阱
- 还原脚本与样本行为不一致 → 回查边界条件(长度/填充):现象——脚本解出的明文与样本自身输出不一样(多/少字节、尾部乱码);原因——边界条件没对齐:填充方式(PKCS7/zero)、长度字段是否含填充、IV 是否每包变、密文尾部是否截断;对策——反编译里逐条核对填充与长度处理代码,脚本里显式实现,再回步骤 4 用已知明文验证
- 解密在壳内 → 先脱壳:现象——在加壳样本里找不到解密函数,或找到的函数只是壳的解压;原因——密文数据/解密逻辑被壳包着,静态看是壳的初始状态([[re-memdump]] 坑 2 同理);对策——先 [[re-anti-analysis]] 脱壳(OEP 后再转储/反编译),脱壳产物重新做定位
- 多轮解密链:现象——解出第一层后仍是乱码/高熵(熵 7.0+);原因——多层加密(先 XOR 再 AES,或嵌套压缩+加密,见 [[re-crypto-id]] 坑 3);对策——每层单独验证(解一层测一次熵与可读性),分层还原;可用"熵下降即前进一层"作为停止条件
- 密钥/IV 顺序用错解出乱码:现象——已知明文验证失败,但算法确定是 AES;原因——key/iv 参数顺序(样本是 key||iv 拼接还是分开传)、密钥字节序、或 IV 复用/固定 IV;对策——把 [[re-crypto-keys]] 的候选(含大小端变体、IV=key 前缀等常见错误实现变体)做成参数组合循环试解,命中即可读性/已知明文判定
- 受限符号集 = 编码不是加密(伪加密):现象——熵 7.9+ 但字节值域明显受限(如只有 66 个符号、分布均匀、无周期),xortool/IC 对所有密钥长度全平;原因——这是"编码 + 单字节 XOR":单字节 XOR 不改变频率分布与符号集(只平移值),多字节 XOR 才会把符号打散成 256 值;对策——收集全部符号值集合,与已知字符集做 XOR 匹配(对 256 个 key 做集合比较,毫秒级,别用穷举):Base64 64 字符 +
\n+== 66 符号、Ascii85 85、hex 16 等;命中后 XOR 还原 → 解码;交叉验证:填充符(如=加密后仅出现 1 次在文件尾)、换行符频率、解码后魔数 - xortool/IC 结果全平 = 换思路的信号:现象——密钥长度候选全部 ~10-20% 且无突出峰值;结论——统计上不存在周期结构,多字节重复密钥 XOR 基本排除,别换参数继续跑;对策——退回观察数据本身(值域/符号集/熵),通常是编码层或一次性密钥流(流密码)
- 伪密文已确认但层数不止一层 → 分层剥离纪律:每层剥完用魔数/可读性验证产物完整性再进下一层;中间产物全部保留命名(可回滚);熵不降 / 解出仍高熵 = 还有外层(如 XOR 外再 Base64、再压缩)
- 像素级 XOR(视觉密码学/图像隐写):现象——两张"随机噪点"图,题目提示叠加;原因——视觉密码学把信息分成两张 share,XOR(或 ADD)像素后可见;对策——
ImageChops.logical_xor或 numpya^b逐像素 XOR 两图(RGB 三通道);结果常是"99.5% 纯白背景 + 极浅灰文字"(文字 254 vs 背景 255)——直接看/反色都不可见,用阈值增强:==255 → 黑、其余 → 白,文字立现;位图小字再按字符网格(5x7)切分逐字读,重复字符用两两位图相似度矩阵验证(如d562333d的重复模式) - ADD 饱和加法是 XOR 的近亲:现象——XOR 结果无内容时;原因——share 可能由加法式秘密共享生成(XOR 得到噪声,ADD/SUB 才出图);对策——同样试
clip(a+b)饱和加法与a-b减法,多运算组合对比 - 新版混淆重 → 老版本回溯定位:现象——最新版核心函数混淆后体积异常庞大,IDA 分析卡顿,硬啃不现实;原因——同一 SDK 早期版本未上重混淆,核心逻辑更清晰;对策——按行为特征(如"同意隐私协议即触发采集")装历史版本包(豌豆荚等渠道)→ 点同意 → 抓包确认最早出现该参数的版本;选行为规范的版本做分析起点(调试方便:spawn/attach 都能复现);老版本还原出的逻辑反过来指导确认新版采集了哪些参数
- 分段/分层加密上报(每段算法不同):现象——抓到的上报请求字段单看都像密文,但统一按一种算法解全是乱码;原因——客户端加密流程分多段:单字段加密 → 分段加密 → 整体加密,每段的算法/密钥不同(如第一层随机数做 key 逐字节加密、第二层固定 key、第三层拼接组合字段后再加密);且字段本身可能是设备采集的风险特征(svc 指令采集、
r_1_0类字段);对策——按"每层单独验证"纪律分层剥(熵降/可读即前进一层,见多轮解密链坑);注意同源 SDK 的"整体加密"可能再套 VM 化算法(约 70 个 handle 模拟基本指令、handle 未混淆时可逐个识别指令语义);key 来源分随机(抓包不可复现)与固定(可静态找)两类,先固定后随机 - 双重 AES + 加密字符串(key/iv 也加密存):现象——确认 AES 后直接解仍失败,或 key/iv 每次会话都变;原因——实现常见套路:第一层 key/iv 固定(以加密字符串形式硬编码在 so,运行时经解密函数解出),第二层 key/iv 每次变化;两次加密间拼接固定前缀(如
03000001)再进同一函数;且加解密可能是同一函数(标志位控制方向);对策——hook 解密函数返回点批量导出全部解密字符串(JNI_OnLoad 前 memcpy 的加密串 → 全局变量 → 解密函数),key/iv 直接在其中搜索;找加密点用 findcrypt 扫特征常量(AES S-box 等)→ xref 定位校验 key/iv 长度(16)的函数;动态 hook 打印两次调用前后数据对照验证
Signals
- GitHub stars
- 57
- Forks
- 8
- Last commit
- Sep 2026
ahel review
K1binfo
installs-packages
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Catalog kind
- skill
- Gateway key
re-crypto-decrypt- Source
- github.com/dslsdzc/rev-skills