- hook_str_magic.js: dfpReport/hyudbwebuif字符串过滤替代魔数(不漏轮次) + 全量请求dump - 采样集: golden+f1..f4+新身份B(0647) — 新身份头12B=旧身份一致(nonce与身份无关) - nonce块: [7cda][版本][69c9f5][计数递增][稳定段] ; 运行时路线终态(Java桥/co-located/回溯全闭) - 触发-捕获-存档 ~40s/轮 全自动; evidence/dfp_live/ 齐全
68 lines
3.1 KiB
JavaScript
68 lines
3.1 KiB
JavaScript
'use strict';
|
|
function emit(row) { try { send(row); } catch (e) {} }
|
|
function btOk(ctx) { try { return Thread.backtrace(ctx, Backtracer.ACCURATE).slice(0, 10).map(a => { const m = Process.findModuleByAddress(a); return m ? m.name + '!' + a.sub(m.base) : a.toString(); }).join(' <- '); } catch (e) { return ''; } }
|
|
const MAGIC = new Uint8Array([0x57, 0x18, 0x82, 0xcf, 0x66, 0x4b, 0xb3, 0x94, 0x01, 0xee]);
|
|
let done = false;
|
|
function scanAndDump(p, n) {
|
|
const hits = [];
|
|
try {
|
|
const u = new Uint8Array(p.readByteArray(n));
|
|
for (let i = 0; i + 10 < n; i++) {
|
|
let ok = true;
|
|
for (let j = 0; j < 10; j++) if (u[i+j] !== MAGIC[j]) { ok = false; break; }
|
|
if (ok) hits.push(i);
|
|
}
|
|
} catch (e) {}
|
|
return hits;
|
|
}
|
|
for (const mod of Process.enumerateModules()) {
|
|
let addr = null;
|
|
try { addr = mod.getExportByName('SSL_write'); } catch (e) {}
|
|
if (addr === null) continue;
|
|
Interceptor.attach(addr, {
|
|
onEnter(args) {
|
|
if (done) return;
|
|
const buf = args[1], num = args[2].toInt32();
|
|
if (num < 40) return;
|
|
try {
|
|
const head = new Uint8Array(buf.readByteArray(Math.min(num, 60)));
|
|
let hit = -1;
|
|
for (let i = 0; i + 10 < head.length; i++) {
|
|
let ok = true;
|
|
for (let j = 0; j < 10; j++) if (head[i+j] !== MAGIC[j]) { ok = false; break; }
|
|
if (ok) { hit = i; break; }
|
|
}
|
|
if (hit < 0) return;
|
|
done = true;
|
|
// 1) full ssl buffer
|
|
const n = Math.min(num, 20000);
|
|
const hex = Array.from(new Uint8Array(buf.readByteArray(n))).map(x => x.toString(16).padStart(2, '0')).join('');
|
|
emit({ event: 'magic-dump', stage: 'ssl', module: mod.name, num, full: hex, bt: btOk(this.context) });
|
|
// 2) co-located: scan the turing modules + a few anonymous big regions for other magic instances + ascii around
|
|
setTimeout(() => {
|
|
try {
|
|
const tg = ['libturingga.so', 'libturingmfa.so', 'libudbauthunify.so', 'libturingsdk'];
|
|
for (const m of Process.enumerateModules()) {
|
|
if (!tg.some(t => m.name.indexOf(t) >= 0)) continue;
|
|
const hits = scanAndDump(m.base, Math.min(m.size, 4096 * 1024));
|
|
for (const off of hits.slice(0, 20)) {
|
|
const at = m.base.add(off);
|
|
const pre = Array.from(new Uint8Array(at.readByteArray(64))).map(x => x.toString(16).padStart(2, '0')).join('');
|
|
const around = [];
|
|
for (let k = -64; k < 2048; k += 64) {
|
|
try {
|
|
const chunk = Array.from(new Uint8Array(at.add(k).readByteArray(64)));
|
|
const s = chunk.map(c => (c >= 32 && c < 127) ? String.fromCharCode(c) : '.').join('');
|
|
if (/[A-Za-z0-9_\-\.\/:]{12,}/.test(s)) around.push({ k, s });
|
|
} catch (e) {}
|
|
}
|
|
emit({ event: 'magic-dump', stage: 'co-located', mod: m.name, off: '0x' + off.toString(16), pre, around: around.slice(0, 12) });
|
|
}
|
|
}
|
|
} catch (e) { emit({ event: 'magic-dump', stage: 'co-err', msg: String(e).slice(0, 120) }); }
|
|
}, 0);
|
|
} catch (e) {}
|
|
},
|
|
});
|
|
}
|