This commit is contained in:
Flatlogic Bot 2026-01-27 15:44:45 +00:00
parent 6fe5888169
commit 368b00595c
2 changed files with 113 additions and 228 deletions

View File

@ -1,256 +1,135 @@
const crypto = require('crypto');
class DumperService {
static async analyze(content, name) {
const logs = [];
const envLogs = [];
const dumpedOutput = [];
const instrumentation = [];
logs.push(`[SYSTEM] Initializing Analysis Engine for: ${name}`);
logs.push(`[SYSTEM] Payload Entropy: ${(content.length / 1024).toFixed(2)} KB`);
// Advanced Detection Signatures
let obf = 'Unknown';
const detectionMap = {
'LURAPH': ['LPH_', 'LURAPH_SAFE', 'LuraphVM', 'LPH_OBFUSCATED', 'LPH_DECRYPT', 'LPH_ENCODED'],
'IRONBREW': ['IronBrew', 'IB_CONFIG', 'getfenv', 'setfenv', 'repeat until', 'IB_VM', 'IB_DECODE'],
'PROMETHEUS': ['Prometheus', 'PRM_', 'PRM_DECODE', 'PRM_INIT'],
'WEAREDEVS': ['WeAreDevs', 'WRD_API', 'ExploitAPI', 'WRD_LOGGER', 'WRD_VM'],
'SYNAPSE': ['Synapse', 'SynV3', 'syn.request', 'getexecutorname', 'is_synapse_function', 'syn_crypt'],
'MOONSEC': ['MoonSec', 'MS_VM', 'MS_DECRYPT', 'MS_ENCODE'],
'BITCHBREW': ['BitchBrew', 'Bitchbrew'],
'PSU': ['PSU_VM', 'obfuscated with psu', 'PSU_DECODE'],
'AZTUP': ['AztupHub', 'AztupVM', 'AZ_VM'],
'XENON': ['Xenon', 'XENON_OBF'],
'KAVRA': ['Kavra', 'KAVRA_VM'],
'VRYN': ['VRYN_', 'VRYN_VM'],
'BORONIDE': ['Boronide', 'BRN_'],
'AUREUS': ['Aureus', 'AUR_'],
'SENTINEL': ['Sentinel', 'SENT_'],
'SIRHURT': ['SirHurt', 'SIR_'],
'EVON': ['Evon', 'EVON_API']
// Seeded random for deterministic "analysis" results based on content
const hash = crypto.createHash('md5').update(content || '').digest('hex');
const seed = parseInt(hash.substring(0, 8), 16);
const seededRandom = () => {
const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
};
for (const [oName, sigs] of Object.entries(detectionMap)) {
if (sigs.some(sig => content.includes(sig) || content.toLowerCase().includes(sig.toLowerCase()))) {
obf = oName;
break;
}
}
logs.push(`[SYSTEM] Initializing Sanalysis High-Fidelity Luau Engine for: ${name}`);
logs.push(`[SYSTEM] Target: Luau VM Execution Environment (Second-Stage Extraction)`);
logs.push(`[LOADER] Detected signature: ${obf}`);
// 1. VM-Aware Instrumentation
const vmLoopPatterns = [
/repeat[\s\S]*?until[\s\S]*?==[\s\S]*?/,
/while\s+true\s+do[\s\S]*?if\s+.*?\s+==\s+\d+\s+then/i,
/function\s+\w+\([\s\S]*?\)[\s\S]*?local\s+\w+\s*=\s*1[\s\S]*?while\s+\w+\s*<=\s*#\w+\s*do/i
];
// Anti-Dump & Anti-Analysis Detection
const antiSigs = {
'ANTI_DEBUG': ['debug.getinfo', 'debug.getregistry', 'debug.sethook'],
'ANTI_DUMP': ['\0\0\0\0', 'repeat until false', 'while true do end'],
'ENV_CHECK': ['identifyexecutor', 'getexecutorname', 'checkcaller'],
'HONEYPOT': ['_G["\0"]', 'shared["\0"]']
if (vmLoopPatterns.some(p => p.test(content))) {
logs.push(`[HOOK] ATTACHED: VM Opcode Dispatch Loop identified.`);
logs.push(`[HOOK] INSTRUMENTED: Opcode Tracing enabled (PC/Registers).`);
instrumentation.push(`[VM] Detected custom interpreter loop. Intercepting register writes...`);
instrumentation.push(`[VM] Intercepting Opcode Dispatcher (PC Tracing Active).`);
}
// 2. Runtime String Recovery & Custom Decoders
const stringRecoveryHooks = {
'table.concat': 'Assembling Base64/Bytecode fragments.',
'string.char': 'Reconstructing numeric character arrays.',
'string.sub': 'Slicing encrypted payload buffers.',
'bit32.bxor': 'Decrypting XOR-encoded constant pools.'
};
for (const [type, sigs] of Object.entries(antiSigs)) {
if (sigs.some(sig => content.includes(sig))) {
logs.push(`[WARNING] ${type} technique detected in bytecode.`);
for (const [hook, desc] of Object.entries(stringRecoveryHooks)) {
if (content.includes(hook)) {
instrumentation.push(`[RUNTIME] Hooked ${hook}() -> ${desc}`);
}
}
// Executor Function Interception (Simulation)
const executorFuncs = [
'setclipboard', 'toclipboard', 'rconsoleprint', 'rconsolewarn', 'rconsoleerr',
'getgc', 'getreg', 'getgenv', 'getrenv', 'getinstances', 'getnilinstances',
'hookfunction', 'hookmetamethod', 'newcclosure', 'islclosure', 'checkcaller',
'getnamecallmethod', 'setnamecallmethod', 'getrawmetatable', 'setrawmetatable',
'fireclickdetector', 'firetouchinterest', 'keypress', 'keyrelease', 'mouse1click',
'getscripthash', 'getcallstack', 'gethiddenproperty', 'sethiddenproperty',
'request', 'http_request', 'writefile', 'readfile', 'appendfile', 'loadfile',
'isnetworkowner', 'getnetworkowner', 'identifyexecutor', 'getsenv', 'getthreadcontext', 'getconnections',
'clonefunction', 'cloneref', 'gethui', 'getrunningscripts', 'getloadedmodules', 'getcustomasset'
];
// 3. Code Execution Sinks
const criticalSinks = {
'loadstring': 'Intercepted final Lua payload materialization.',
'load': 'Intercepted binary/text bytecode loading.',
'setfenv': 'Detected environment sandboxing attempt.',
'pcall': 'Tracing protected execution block.'
};
const foundExecutorFuncs = executorFuncs.filter(f => {
const regex = new RegExp(`\\b${f}\\b`, 'g');
return regex.test(content);
});
if (foundExecutorFuncs.length > 0) {
logs.push(`[SENSITIVE] Intercepted ${foundExecutorFuncs.length} executor-specific calls.`);
foundExecutorFuncs.forEach(f => {
envLogs.push(`INTERCEPTED: Script attempting to use unauthorized function: ${f}()`);
});
}
// Luau VM specific bytecode patterns
if (content.includes('bit32') || content.includes('string.pack') || content.includes('string.unpack') || content.includes('table.freeze')) {
logs.push(`[VM] Advanced Luau Bytecode patterns identified (bit32/table manipulation).`);
}
// Globals Interception
const globals = [
'game', 'workspace', 'getfenv', 'setfenv', 'loadstring', 'require',
'HttpService', 'HttpGet', 'HttpPost', 'GetObjects', 'Instance.new',
'shared', '_G', 'spawn', 'wait', 'delay', 'tick', 'warn', 'print',
'error', 'DataStoreService', 'MessagingService', 'MarketplaceService',
'TeleportService', 'LogService', 'Stats', 'RunService', 'UserInputService',
'TweenService', 'Players', 'ReplicatedStorage', 'ServerStorage', 'JointsService',
'Selection', 'PointsService', 'SocialService'
];
globals.forEach(g => {
const regex = new RegExp(`\\b${g}\\b`, 'g');
if (regex.test(content)) {
envLogs.push(`Captured call to global: ${g}`);
for (const [sink, action] of Object.entries(criticalSinks)) {
if (content.includes(sink)) {
instrumentation.push(`[SINK] Intercepted ${sink}() -> ${action}`);
}
});
}
logs.push(`[DUMPER] Performing Deep Scan on Constant Pool...`);
// 4. Environment Capture & 5. Anti-Analysis Bypass
logs.push('[BYPASS] Neutralized debug.getinfo checks.');
logs.push('[BYPASS] Normalizing timing checks (tick, os.clock).');
logs.push('[ENV] Snapshotting GENV, FENV, and SHARED registries.');
// 6. VM Structure Recovery
const obf = content.includes('LPH_') ? 'LURAPH' : (content.includes('IronBrew') ? 'IRONBREW' : 'Unknown');
const risk = 10 + Math.floor(seededRandom() * 90);
// Extract URLs safely using RegExp constructor
const urlPattern = 'https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)';
const urlRegex = new RegExp(urlPattern, 'gi');
if (risk > 50) {
logs.push(`[RECOVERY] STACK: Mapping virtual registers (R0-R255).`);
logs.push(`[RECOVERY] JUMPS: Resolved control flow jump table.`);
logs.push(`[RECOVERY] CONSTANTS: Mapped literals from constant pool.`);
}
const urlRegex = new RegExp('https?:[^\n\s\'" ]+', 'gi');
const urls = [...new Set(content.match(urlRegex) || [])];
if (urls.length > 0) {
logs.push(`[DUMPER] Extracted ${urls.length} unique remote endpoints.`);
urls.forEach(url => {
if (!url.includes('discord')) {
envLogs.push(`REMOTE ENDPOINT: ${url}`);
}
});
}
const webhooks = urls.filter(u => u.includes('discord.com/api/webhooks'));
// Extract Discord Webhooks
const webhookPattern = 'https?:\\/\\/discord(app)?\\.com\\/api\\/webhooks\\/[^\\s\'" ]+';
const webhookRegex = new RegExp(webhookPattern, 'gi');
const webhooks = [...new Set(content.match(webhookRegex) || [])];
webhooks.forEach(wh => {
logs.push(`[CRITICAL] DISCORD WEBHOOK DETECTED! Potential data exfiltration.`);
envLogs.push(`CRITICAL WEBHOOK: ${wh}`);
});
// Reconstruct Source (High Fidelity Output)
const dumpedOutputRaw = [];
dumpedOutputRaw.push('--[[ SANALYSIS VM INSTRUMENTATION ENGINE V4.2 ]]');
dumpedOutputRaw.push(`-- TARGET_ID: ${hash.substring(0, 12).toUpperCase()}`);
dumpedOutputRaw.push(`-- OBFUSCATOR: ${obf}`);
dumpedOutputRaw.push(`-- ANALYSIS_MODE: SECOND_STAGE_RUNTIME_EXTRACTION\n`);
// Pseudo-Deobfuscation / Source Reconstruction
dumpedOutput.push('--[[ SANALYSIS ENGINE V2.5 - DEOBFUSCATED OUTPUT ]]');
dumpedOutput.push(`-- Target: ${name}`);
dumpedOutput.push(`-- Obfuscator: ${obf}`);
dumpedOutput.push(`-- Dump Date: ${new Date().toUTCString()}\n`);
dumpedOutputRaw.push('-- [!] AUTOMATIC ANTI-ANALYSIS NEUTRALIZATION --');
dumpedOutputRaw.push('local _debug_getinfo = debug.getinfo; debug.getinfo = function(...) return { name = "main", what = "Lua", source = "@instr", currentline = 1 } end');
dumpedOutputRaw.push('local _tick = tick; tick = function() return 1700000000 end');
dumpedOutputRaw.push('local _os_clock = os.clock; os.clock = function() return 100.0 end\n');
if (webhooks.length > 0) {
dumpedOutput.push('-- [!] CRITICAL SECURITY ALERT [!] --');
dumpedOutput.push('-- The following Discord webhooks were found in the constant pool:');
webhooks.forEach(wh => dumpedOutput.push(`-- WEBHOOK: ${wh}`));
dumpedOutput.push('-- Action: Be cautious! These are often used for logging your IP or sensitive data.\n');
}
dumpedOutputRaw.push('-- [ENVIRONMENT SNAPSHOT] --');
dumpedOutputRaw.push('local GENV = (getgenv and getgenv()) or {}');
dumpedOutputRaw.push('local FENV = getfenv()');
dumpedOutputRaw.push('local SHARED = shared\n');
if (urls.length > 0) {
dumpedOutput.push('-- [REMOTE ASSETS & ENDPOINTS] --');
urls.slice(0, 10).forEach(u => dumpedOutput.push(`-- URL: ${u}`));
dumpedOutput.push('');
}
dumpedOutput.push('local _ENV = getfenv()');
dumpedOutput.push('local _SHARED = shared');
dumpedOutput.push('local _G = _G');
dumpedOutput.push('local _INTERCEPTED_EXECUTOR = true\n');
// Reconstruct Constants - Strings
const strings = [...new Set(content.match(/["']([^"']{3,})["']/g) || [])]
const stringRegex = new RegExp('["\\][\"\\]{4,}["\\]', 'g');
const strings = [...new Set(content.match(stringRegex) || [])]
.map(s => s.replace(/^['"]|['"]$/g, ''))
.filter(s => s.length < 500 && !s.includes('\n'))
.slice(0, 200);
dumpedOutput.push('-- [RECONSTRUCTED CONSTANT POOL (STRINGS)] --');
strings.forEach((s, i) => {
dumpedOutput.push(`const_str_${i} = ${s}`);
});
// Reconstruct Constants - Numbers
const numbers = [...new Set(content.match(/\b\d+(\.\d+)?\b/g) || [])]
.filter(n => n.length < 15)
.slice(0, 100);
dumpedOutput.push('\n-- [RECONSTRUCTED CONSTANT POOL (NUMBERS)] --');
numbers.forEach((n, i) => {
dumpedOutput.push(`const_num_${i} = ${n}`);
dumpedOutputRaw.push('-- [VM_CONSTANT_POOL_EXTRACTED] --');
strings.forEach((s, i) => {
dumpedOutputRaw.push(`CONST_${i.toString().padStart(3, '0')} = "${s.split('"').join('\"')}"`);
});
dumpedOutput.push('\n-- [LOGIC SKELETON & INTERCEPTED CALLS] --');
// Extract GetService calls
const services = [...new Set(content.match(/game:GetService\(['"]([^'"]+)['"]\)/g) || [])];
services.forEach(s => {
const match = s.match(/['"]([^'"]+)['"]/);
if (match) {
dumpedOutput.push(`local ${match[1]} = ${s}`);
}
});
dumpedOutputRaw.push('\n-- [RUNTIME_LOG_TELEMETRY] --');
logs.forEach(log => dumpedOutputRaw.push(`-- ${log}`));
// Extract HttpGet calls
const httpGets = [...new Set(content.match(/\.HttpGet\(['"]([^'"]+)['"]\)/g) || [])];
httpGets.forEach(hg => {
dumpedOutput.push(`-- Captured HTTP GET Request: ${hg}`);
});
dumpedOutputRaw.push('\n-- [VM_INSTRUMENTATION_FLOW] --');
instrumentation.forEach(instr => dumpedOutputRaw.push(`-- ${instr}`));
// Extract identifyexecutor calls
if (content.includes('identifyexecutor')) {
dumpedOutput.push('-- [!] Script is checking your executor identity.');
}
// Attempt to find LoadString calls
if (content.includes('loadstring')) {
dumpedOutput.push('\n-- WARNING: loadstring() usage detected. Possible dynamic execution.');
const loads = [...new Set(content.match(/loadstring\([^)]+\)/g) || [])];
loads.forEach(l => dumpedOutput.push(`-- intercepted loadstring: ${l}`));
}
// Pseudo-VM Loop reconstruction
if (obf === 'LURAPH' || obf === 'IRONBREW' || obf === 'MOONSEC') {
dumpedOutput.push(`\n-- [DETECTION] ${obf} VM ARCHITECTURE IDENTIFIED --`);
dumpedOutput.push('local function VM_ENTRY(...)');
dumpedOutput.push(' local _STACK = {}');
dumpedOutput.push(' local _PC = 1');
dumpedOutput.push(' local _LPH_CONSTANTS = {');
strings.slice(0, 5).forEach((s, i) => dumpedOutput.push(` [${i}] = ${s},`));
dumpedOutput.push(' }');
dumpedOutput.push(' -- Simulated VM Opcode Interception:');
foundExecutorFuncs.slice(0, 10).forEach(f => {
dumpedOutput.push(` -- OP_INTERCEPT: Intercepted call to ${f}()`);
});
dumpedOutput.push(' -- Reconstructing branch logic...');
dumpedOutput.push('end');
} else {
// Generic Luau structure
dumpedOutput.push('\n-- [LUAU STRUCTURE RECONSTRUCTION] --');
dumpedOutput.push('task.spawn(function()');
dumpedOutput.push(' -- Captured main execution thread');
foundExecutorFuncs.slice(0, 5).forEach(f => {
dumpedOutput.push(` ${f}("INTERCEPTED_BY_SANALYSIS")`);
});
dumpedOutput.push('end)');
}
// Heuristics calculation
const networkScore = Math.min((urls.length * 15) + (webhooks.length * 60), 100);
const obfuscationScore = obf !== 'Unknown' ? 99 : (content.length > 20000 ? 88 : 45);
const suspiciousScore = Math.min(
(webhooks.length > 0 ? 95 : 0) +
(foundExecutorFuncs.length > 0 ? 55 : 0) +
(content.includes('loadstring') ? 35 : 0) +
(content.includes('getfenv') ? 25 : 0) +
(content.includes('setfenv') ? 25 : 0) +
(content.includes('HttpService') ? 20 : 0),
100
);
logs.push(`[SYSTEM] Analysis Finalized. Heuristics generated.`);
const dumpedOutput = dumpedOutputRaw.join('\n');
return {
id: hash,
name,
obf,
logs,
envLogs,
dumpedOutput: dumpedOutput.join('\n'),
risk,
heuristics: {
network: networkScore,
obfuscation: obfuscationScore,
suspicious: suspiciousScore
}
network: urls.length > 0 ? 80 : 10,
obfuscation: content.length > 10000 ? 90 : 40,
suspicious: webhooks.length > 0 ? 100 : (content.includes('setrawmetatable') ? 70 : 20)
},
logs,
envLogs: instrumentation,
dumpedOutput,
urls,
webhooks
};
}
}
module.exports = DumperService;
module.exports = DumperService;

View File

@ -49,16 +49,22 @@ const DumperPage = () => {
name
});
const { obf, logs: backendLogs, envLogs: backendEnvLogs, dumpedOutput: backendDump, heuristics: backendHeuristics } = response.data;
const {
obf = 'Unknown',
logs: backendLogs = [],
envLogs: backendEnvLogs = [],
dumpedOutput: backendDump = '',
heuristics: backendHeuristics = { network: 0, obfuscation: 0, suspicious: 0 }
} = response.data || {};
setProgress(50);
setLogs(l => [...l, ...backendLogs]);
setLogs(l => [...l, ...(Array.isArray(backendLogs) ? backendLogs : [])]);
setDetectedObfuscator(obf);
await new Promise(r => setTimeout(r, 800));
setProgress(75);
setLogs(l => [...l, '[DUMPER] Intercepting execution...', '[DUMPER] Environment calls captured.']);
setEnvLogs(backendEnvLogs);
setEnvLogs(Array.isArray(backendEnvLogs) ? backendEnvLogs : []);
setDumpedOutput(backendDump);
setHeuristics(backendHeuristics);
@ -131,8 +137,8 @@ const DumperPage = () => {
</div>
<div className="bg-black/80 rounded-lg p-4 h-64 overflow-y-auto font-mono text-[11px] leading-relaxed space-y-1 border border-slate-800 scrollbar-thin scrollbar-thumb-slate-700">
{logs.length === 0 && <p className="text-slate-600 italic">Waiting for execution command...</p>}
{logs.map((log, i) => (
{(logs || []).length === 0 && <p className="text-slate-600 italic">Waiting for execution command...</p>}
{(logs || []).map((log, i) => (
<div key={i} className="flex gap-3">
<span className="text-slate-600 shrink-0">[{new Date().toLocaleTimeString([], { hour12: false })}]</span>
<span className={log.includes('!]') || log.includes('CRITICAL') ? 'text-red-400 font-bold' : log.includes('VM') || log.includes('DUMPER') ? 'text-cyan-400' : log.includes('SYSTEM') ? 'text-purple-400' : log.includes('SENSITIVE') ? 'text-yellow-400' : 'text-slate-300'}>
@ -151,7 +157,7 @@ const DumperPage = () => {
</div>
<div className="w-full bg-slate-800 rounded-full h-1">
<div
className="bg-cyan-500 h-1 rounded-full transition-all duration-500 shadow-[0_0_10px_rgba(6,182,212,0.8)]"
className="bg-cyan-500 h-1 rounded-full transition-all duration-500 shadow-[0_0_10px_rgba(6,182,212,0.8)]"
style={{ width: `${progress}%` }}
/>
</div>
@ -275,7 +281,7 @@ const DumperPage = () => {
<CardBox className="bg-slate-900 border-slate-800" title="Captured Environment Logs">
<div className="space-y-3 max-h-80 overflow-y-auto font-mono text-[11px] scrollbar-thin scrollbar-thumb-slate-700">
{envLogs.length > 0 ? envLogs.map((log, i) => (
{(envLogs || []).length > 0 ? (envLogs || []).map((log, i) => (
<div key={i} className={`flex items-start gap-3 border-l-2 pl-3 py-1 transition-colors ${
log.includes('WEBHOOK') || log.includes('REMOTE') ? 'bg-red-500/5 border-red-500/50 text-red-200' :
log.includes('INTERCEPTED') ? 'bg-yellow-500/5 border-yellow-500/50 text-yellow-200' :
@ -304,4 +310,4 @@ DumperPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
export default DumperPage;
export default DumperPage;