executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-crypto-keys密钥与口令提取:硬编码、内存搜索、资源。 触发词:找密钥、硬编码、key extraction、口令
Independent GitHub snapshot · Automated classification · Original documentation governs
所有工具先验证再使用。静态搜索可免沙箱;内存转储/动态环节按 [[re-memdump]] 默认转储优先 + [[re-analyze/platform-tips]] 最高原则(运行样本进沙箱)。
apt install binutils / dnf install binutils / pacman -S binutils(多数自带)strings.exe(Sysinternals)strings --version(GNU 版有 --version)ghidra(GUI)或 rz-ghidra 插件可用;rizin -vgcore -o out <pid> 转储;转储时机按明文/代码 materialization 定(单层壳 OEP 附近通常合适,OEP 非通用判据,见 [[re-analyze/platform-tips]] 关键经验)file out 确认为 ELF core,eu-stack -e out 能跑按顺序执行,每步记下结果。策略顺序:先静态后动态(见坑 3),每步产物(密钥/口令 + 来源证据:偏移、函数名、转储路径)记录供 [[re-crypto-decrypt]] 使用。
静态:strings / 交叉引用找硬编码:
strings -n 6 sample.bin | grep -iE 'key|secret|pass|token|crypt|iv' | head -50
strings -el sample.bin | grep -iE 'key|secret|pass' | head -20 # UTF-16LE(Windows 常见)
strings -n 8 sample.bin | head -100 # 全量扫描人工过一遍
Search > Memory / :> /v 0x...):32 字节十六进制串、重复的随机数据段内存:转储后搜密钥模式(16/32 字节熵块、口令可打印串):
gcore -o out <pid> # 默认转储([[re-memdump]]),按 materialization 定时机
data = open('out','rb').read()
import collections, math
# 16/32 字节高熵块(AES-128/256 密钥候选)
def ent(blk):
c = collections.Counter(blk); n = len(blk)
return -sum((v/n)*math.log2(v/n) for v in c.values())
for base in range(0, len(data)-32, 32):
blk = data[base:base+32]
if ent(blk) > 7.0 and 16 <= len(set(blk)) <= 24:
print(f"0x{base:x}: 32B 高熵块")
# 口令/可打印串
import re
for m in re.finditer(rb'[ -~]{8,64}', data):
s = m.group()
if any(k in s.lower() for k in (b'key', b'pass', b'secret', b'pwd')):
print(f"0x{m.start():x}: {s}")
资源文件(.rsrc / 嵌入 blob):
llvm-objdump -s -j .rsrc sample.exe 或 Ghidra 看资源段;7z x sample.exe 可解出嵌入的 icon/version/自定义资源.rodata 里的嵌入 blob(objdump -s -j .rodata);结合 [[re-firmware]] 经验——固件里密钥常在配置文件/默认证书里*导入表线索(Crypt 函数附近)**:
objdump -p sample.exe | grep Crypt / Ghidra Imports 窗口找 CryptEncrypt/CryptDecrypt/BCrypt*/RSA*/EVP_*(OpenSSL)CryptSetKeyParam 的 pbKeyData 参数b CryptSetKeyParam 后看 pbKeyData 指向的内存——但注意 [[re-analyze/platform-tips]] 最高原则:运行进沙箱密钥派生函数(PBKDF)还原:
PBKDF2/scrypt/bcrypt/EVP_BytesToKey 调用 → 密钥 = KDF(口令, 盐, 迭代次数),逐参数提取:口令(硬编码串或用户输入)、盐(固定字节或上下文)、迭代次数(常量)pip install cryptography / hashlib 自带 PBKDF2):
import hashlib
key = hashlib.pbkdf2_hmac('sha256', b'passphrase', b'<salt>', 100000, dklen=32)
print(key.hex())
RAND_bytes 生成或服务器下发,根本不在样本里(白盒攻击之外无解);对策——诚实报告:本地无可提取密钥,改走密钥派生拦截(hook RAND_bytes/KDF 输入)、算法侧攻击(若解密结果可被已知明文验证)或回 [[re-malware]] 看密钥是否由 C2 下发