diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9116783 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM node:18-bullseye + +# Set working directory +WORKDIR /app + +# Copy package info dulu +COPY package*.json ./ + +# Install SEMUA dependencies (hapus --production agar lebih aman) +RUN npm install + +# Copy sisa file +COPY . . + +# Set Environment Variable +ENV PORT=3000 +ENV NODE_ENV=production + +# Buka Port +EXPOSE 3000 + +# Jalankan server +CMD ["node", "server.js"] diff --git a/package.json b/package.json new file mode 100644 index 0000000..17df815 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "prometheus-web", + "version": "1.0.0", + "description": "Obfuscator", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "express": "^4.18.2" + }, + "engines": { + "node": ">=18.0.0" + } +} diff --git a/readme.md b/readme.md index 4040509..c25c01f 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# :fire: Prometheus +# :fire: Prometheus 3 [![Test](https://github.com/prometheus-lua/Prometheus/actions/workflows/Test.yml/badge.svg)](https://github.com/prometheus-lua/Prometheus/actions/workflows/Test.yml) ## Description Prometheus is a Lua obfuscator written in pure Lua. diff --git a/server.js b/server.js new file mode 100644 index 0000000..73105cd --- /dev/null +++ b/server.js @@ -0,0 +1,398 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const cors = require('cors'); +const crypto = require('crypto'); + +const app = express(); +const PORT = process.env.PORT || 3000; + +// Middleware +app.use(cors()); +app.use(bodyParser.json({ limit: '50mb' })); +app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' })); + +// ==================== HTML UI ==================== +app.get('/', (req, res) => { + res.send(` + + + + + + Prometheus Advanced + + + +
+

🔐 Prometheus Advanced

+

Self-Hosted Lua Obfuscator

+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

📝 Input Script

+ +
+
+

🔐 Output

+ +
+
+ +
+ + + +
+ +
+
+ + + + + `); +}); + +// ==================== OBFUSCATOR LOGIC ==================== + +class LuaObfuscator { + constructor(settings = {}) { + this.settings = settings; + this.level = settings.level || 3; + this.stats = { stringsEncrypted: 0, varsRenamed: 0 }; + this.encryptionKey = this.generateKey(16); + this.varCounter = 0; + this.reserved = new Set([ + 'and','break','do','else','elseif','end','false','for','function','goto', + 'if','in','local','nil','not','or','repeat','return','then','true','until','while', + 'game','workspace','script','print','warn','error','pcall','loadstring' + ]); + } + + generateKey(length) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + for (let i = 0; i < length; i++) result += chars.charAt(Math.floor(Math.random() * chars.length)); + return result; + } + + randomILVar() { + const chars = ['I', 'l', '1']; + let result = chars[Math.floor(Math.random() * 2)]; + let length = 8 + Math.floor(Math.random() * 8); + for (let i = 1; i < length; i++) result += chars[Math.floor(Math.random() * chars.length)]; + return result; + } + + randomInt(min = 1000, max = 99999) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + xorEncrypt(str, key) { + let result = []; + for (let i = 0; i < str.length; i++) { + result.push(str.charCodeAt(i) ^ key.charCodeAt(i % key.length)); + } + return result; + } + + generateStringDecryptor() { + const funcName = this.randomILVar(); + const keyVar = this.randomILVar(); + const dataVar = this.randomILVar(); + const resultVar = this.randomILVar(); + const indexVar = this.randomILVar(); + + return { + name: funcName, + code: `local ${funcName}=(function(${dataVar},${keyVar})local ${resultVar}="";for ${indexVar}=1,#${dataVar} do ${resultVar}=${resultVar}..string.char(bit32.bxor(${dataVar}[${indexVar}],string.byte(${keyVar},(${indexVar}-1)%#${keyVar}+1)));end;return ${resultVar};end);` + }; + } + + encryptString(str) { + if (str.length === 0) return '""'; + if (str.length > 200) return null; + this.stats.stringsEncrypted++; + const encrypted = this.xorEncrypt(str, this.encryptionKey); + return { data: `{${encrypted.join(',')}}`, key: `"${this.encryptionKey}"` }; + } + + generateJunkCode(count = 5) { + const junk = []; + for (let i = 0; i < count; i++) { + const v1 = this.randomILVar(); + const n1 = this.randomInt(); + junk.push(`local ${v1}=${n1};`); + } + return junk.join(''); + } + + generateOpaquePredicate(isTrue = true) { + const n1 = this.randomInt(1, 1000); + return isTrue ? `(${n1}==${n1})` : `(${n1}~=${n1})`; + } + + generateAntiDebug() { + const checkVar = this.randomILVar(); + return `local ${checkVar}=(function()pcall(function()if getgenv and(getgenv().SimpleSpy or getgenv().RemoteSpy)then while true do end end end)return true end)();`; + } + + generateEnvWrapper() { + const envVar = this.randomILVar(); + return `local ${envVar}=setmetatable({},{__index=function(s,k)return rawget(s,k)or getfenv()[k]or _G[key]end});setfenv(1,${envVar});`; + } + + obfuscate(script) { + let result = script; + const stringDecryptor = this.generateStringDecryptor(); + let needsDecryptor = false; + + // 1. String Encryption + if (this.settings.strEncrypt !== false) { + result = result.replace(/"([^"\\]*(\\.[^"\\]*)*)"/g, (match, content) => { + if (content.length === 0 || content.length > 150) return match; + const encrypted = this.encryptString(content); + if (encrypted) { + needsDecryptor = true; + return `${stringDecryptor.name}(${encrypted.data},${encrypted.key})`; + } + return match; + }); + result = result.replace(/'([^'\\]*(\\.[^'\\]*)*)'/g, (match, content) => { + if (content.length === 0 || content.length > 150) return match; + const encrypted = this.encryptString(content); + if (encrypted) { + needsDecryptor = true; + return `${stringDecryptor.name}(${encrypted.data},${encrypted.key})`; + } + return match; + }); + } + + // 2. Variable Mangling + if (this.settings.varMangle !== false) { + const varMap = new Map(); + const localPattern = /local\s+([a-zA-Z_][a-zA-Z0-9_]*)/g; + let match; + const tempScript = script; + + while ((match = localPattern.exec(tempScript)) !== null) { + const varName = match[1]; + if (!varMap.has(varName) && !this.reserved.has(varName)) { + varMap.set(varName, this.randomILVar()); + this.stats.varsRenamed++; + } + } + varMap.forEach((newName, oldName) => { + const regex = new RegExp(`\\b${oldName}\\b`, 'g'); + result = result.replace(regex, newName); + }); + } + + // 3. Final Build + let output = []; + + // Header (Fixed Newline) + output.push(`-- Protected with Prometheus Advanced | ${new Date().toISOString().split('T')[0]}`); + + if (this.settings.vmWrapper !== false) { + const vmFunc = this.randomILVar(); + output.push(`local ${vmFunc}=(function()`); + + if (this.settings.envWrapper !== false) output.push(this.generateEnvWrapper()); + if (this.settings.antiDebug !== false) output.push(this.generateAntiDebug()); + if (this.settings.deadCode !== false) output.push(this.generateJunkCode(5)); + if (needsDecryptor) output.push(stringDecryptor.code); + + if (this.settings.controlFlow !== false) { + const condVar = this.randomILVar(); + output.push(`local ${condVar}=${this.generateOpaquePredicate(true)};`); + output.push(`if ${condVar} then`); + output.push(result); + + // Watermark INSIDE control flow + if (this.settings.watermark) { + output.push(`local ${this.randomILVar()}="Protected by Prometheus";`); + } + + output.push('end;'); + } else { + output.push(result); + // Watermark INSIDE wrapper + if (this.settings.watermark) { + output.push(`local ${this.randomILVar()}="Protected by Prometheus";`); + } + } + + output.push(`end);return ${vmFunc}();`); + } else { + if (needsDecryptor) output.push(stringDecryptor.code); + output.push(result); + if (this.settings.watermark) { + output.push(`local ${this.randomILVar()}="Protected by Prometheus";`); + } + } + + return output.join('\n'); + } +} + +// API Route +app.post('/api/obfuscate', (req, res) => { + try { + const { script, settings } = req.body; + if (!script || typeof script !== 'string') return res.json({ success: false, error: 'No script' }); + + const obfuscator = new LuaObfuscator(settings || {}); + const result = obfuscator.obfuscate(script); + + res.json({ success: true, result: result }); + } catch (error) { + res.json({ success: false, error: error.message }); + } +}); + +// Start Server (BIND TO 0.0.0.0 for Render) +app.listen(PORT, '0.0.0.0', () => { + console.log(`🚀 Prometheus running on port ${PORT}`); +});