38 lines
1.9 KiB
JavaScript
38 lines
1.9 KiB
JavaScript
// Bounded decoding for common wire encodings. This is not arbitrary deobfuscation.
|
|||
|
|
export function inspectionTextVariants(text,maxBytes){
|
||
|
|
const values=[],seen=new Set();let size=0,candidates=0;
|
||
|
|
const budget=Math.min(maxBytes*4,16*1024*1024);
|
||
|
|
function add(value,depth){
|
||
|
|
if(typeof value!=='string'||seen.has(value))return;
|
||
|
|
if(depth>3)throw Error('Inspection normalization limit');
|
||
|
|
const bytes=Buffer.byteLength(value);
|
||
|
|
if(values.length>=64||bytes>maxBytes||size+bytes>budget)throw Error('Inspection normalization limit');
|
||
|
|
if(value.includes('\0'))return;
|
||
|
|
seen.add(value);size+=bytes;values.push({value,depth});
|
||
|
|
}
|
||
|
|
add(text,0);
|
||
|
|
for(let i=0;i<values.length;i++){
|
||
|
|
const {value,depth}=values[i];
|
||
|
|
try{add(decodeURIComponent(value.replace(/\+/g,' ')),depth+1);}catch(error){if(error.message==='Inspection normalization limit')throw error;}
|
||
|
|
try{const parsed=JSON.parse(value);const queue=[parsed];let nodes=0;
|
||
|
|
while(queue.length){if(++nodes>4096)throw Error('Inspection normalization limit');const node=queue.pop();
|
||
|
|
if(typeof node==='string')add(node,depth+1);
|
||
|
|
else if(node&&typeof node==='object'){
|
||
|
|
const children=Object.values(node);
|
||
|
|
if(nodes+queue.length+children.length>4096)throw Error('Inspection normalization limit');
|
||
|
|
for(const child of children)queue.push(child);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}catch(error){if(error.message==='Inspection normalization limit')throw error;}
|
||
|
|
for(const match of value.matchAll(/[A-Za-z0-9+/_-]{12,}={0,2}/g)){
|
||
|
|
const encoded=match[0].replace(/-/g,'+').replace(/_/g,'/'),raw=Buffer.from(encoded,'base64');
|
||
|
|
if(raw.toString('base64').replace(/=+$/,'')!==encoded.replace(/=+$/,''))continue;
|
||
|
|
try{const decoded=new TextDecoder('utf-8',{fatal:true}).decode(raw);
|
||
|
|
if(decoded.includes('\0'))continue;
|
||
|
|
if(++candidates>256)throw Error('Inspection normalization limit');
|
||
|
|
add(decoded,depth+1);
|
||
|
|
}catch(error){if(error.message==='Inspection normalization limit')throw error;}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return values.map(row=>row.value);
|
||
|
|
}
|